001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kim.api.identity.phone;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.CoreConstants;
020import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
021import org.kuali.rice.core.api.mo.ModelBuilder;
022import org.kuali.rice.kim.api.KimApiConstants;
023import org.kuali.rice.kim.api.identity.CodedAttribute;
024import org.w3c.dom.Element;
025
026import javax.xml.bind.annotation.XmlAccessType;
027import javax.xml.bind.annotation.XmlAccessorType;
028import javax.xml.bind.annotation.XmlAnyElement;
029import javax.xml.bind.annotation.XmlElement;
030import javax.xml.bind.annotation.XmlRootElement;
031import javax.xml.bind.annotation.XmlType;
032import java.io.Serializable;
033import java.util.Collection;
034
035@XmlRootElement(name = EntityPhone.Constants.ROOT_ELEMENT_NAME)
036@XmlAccessorType(XmlAccessType.NONE)
037@XmlType(name = EntityPhone.Constants.TYPE_NAME, propOrder = {
038    EntityPhone.Elements.ID,
039    EntityPhone.Elements.ENTITY_TYPE_CODE,
040    EntityPhone.Elements.ENTITY_ID,
041    EntityPhone.Elements.PHONE_TYPE,
042    EntityPhone.Elements.COUNTRY_CODE,
043    EntityPhone.Elements.PHONE_NUMBER,
044    EntityPhone.Elements.EXTENSION_NUMBER,
045    EntityPhone.Elements.FORMATTED_PHONE_NUMBER,
046    EntityPhone.Elements.COUNTRY_CODE_UNMASKED,
047    EntityPhone.Elements.PHONE_NUMBER_UNMASKED,
048    EntityPhone.Elements.EXTENSION_NUMBER_UNMASKED,
049    EntityPhone.Elements.FORMATTED_PHONE_NUMBER_UNMASKED,
050    EntityPhone.Elements.SUPPRESS_PHONE,
051    EntityPhone.Elements.DEFAULT_VALUE,
052    EntityPhone.Elements.ACTIVE,
053    CoreConstants.CommonElements.VERSION_NUMBER,
054    CoreConstants.CommonElements.OBJECT_ID,
055    CoreConstants.CommonElements.FUTURE_ELEMENTS
056})
057public final class EntityPhone extends AbstractDataTransferObject
058    implements EntityPhoneContract
059{
060
061    @XmlElement(name = Elements.ID, required = false)
062    private final String id;
063    @XmlElement(name = Elements.ENTITY_TYPE_CODE, required = false)
064    private final String entityTypeCode;
065    @XmlElement(name = Elements.ENTITY_ID, required = false)
066    private final String entityId;
067    @XmlElement(name = Elements.PHONE_TYPE, required = false)
068    private final CodedAttribute phoneType;
069    @XmlElement(name = Elements.PHONE_NUMBER, required = false)
070    private final String phoneNumber;
071    @XmlElement(name = Elements.EXTENSION_NUMBER, required = false)
072    private final String extensionNumber;
073    @XmlElement(name = Elements.COUNTRY_CODE, required = false)
074    private final String countryCode;
075    @XmlElement(name = Elements.PHONE_NUMBER_UNMASKED, required = false)
076    private final String phoneNumberUnmasked;
077    @XmlElement(name = Elements.EXTENSION_NUMBER_UNMASKED, required = false)
078    private final String extensionNumberUnmasked;
079    @XmlElement(name = Elements.COUNTRY_CODE_UNMASKED, required = false)
080    private final String countryCodeUnmasked;
081    @XmlElement(name = Elements.FORMATTED_PHONE_NUMBER, required = false)
082    private final String formattedPhoneNumber;
083    @XmlElement(name = Elements.FORMATTED_PHONE_NUMBER_UNMASKED, required = false)
084    private final String formattedPhoneNumberUnmasked;
085    @XmlElement(name = Elements.SUPPRESS_PHONE, required = false)
086    private final boolean suppressPhone;
087    @XmlElement(name = Elements.DEFAULT_VALUE, required = false)
088    private final boolean defaultValue;
089    @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
090    private final Long versionNumber;
091    @XmlElement(name = CoreConstants.CommonElements.OBJECT_ID, required = false)
092    private final String objectId;
093    @XmlElement(name = Elements.ACTIVE, required = false)
094    private final boolean active;
095    @SuppressWarnings("unused")
096    @XmlAnyElement
097    private final Collection<Element> _futureElements = null;
098
099    /**
100     * Private constructor used only by JAXB.
101     *
102     */
103    private EntityPhone() {
104        this.id = null;
105        this.entityId = null;
106        this.entityTypeCode = null;
107        this.phoneType = null;
108        this.phoneNumber = null;
109        this.extensionNumber = null;
110        this.countryCode = null;
111        this.phoneNumberUnmasked = null;
112        this.extensionNumberUnmasked = null;
113        this.countryCodeUnmasked = null;
114        this.formattedPhoneNumber = null;
115        this.formattedPhoneNumberUnmasked = null;
116        this.suppressPhone = false;
117        this.defaultValue = false;
118        this.versionNumber = null;
119        this.objectId = null;
120        this.active = false;
121    }
122
123    private EntityPhone(Builder builder) {
124        this.id = builder.getId();
125        this.entityId = builder.getEntityId();
126        this.entityTypeCode = builder.getEntityTypeCode();
127        this.phoneType = (builder.getPhoneType() != null) ? builder.getPhoneType().build() : null;
128        this.phoneNumber = builder.getPhoneNumber();
129        this.extensionNumber = builder.getExtensionNumber();
130        this.countryCode = builder.getCountryCode();
131        this.phoneNumberUnmasked = builder.getPhoneNumberUnmasked();
132        this.extensionNumberUnmasked = builder.getExtensionNumberUnmasked();
133        this.countryCodeUnmasked = builder.getCountryCodeUnmasked();
134        this.formattedPhoneNumber = builder.getFormattedPhoneNumber();
135        this.formattedPhoneNumberUnmasked = builder.getFormattedPhoneNumberUnmasked();
136        this.suppressPhone = builder.isSuppressPhone();
137        this.defaultValue = builder.isDefaultValue();
138        this.versionNumber = builder.getVersionNumber();
139        this.objectId = builder.getObjectId();
140        this.active = builder.isActive();
141    }
142
143    @Override
144    public String getId() {
145        return this.id;
146    }
147
148    @Override
149    public String getEntityId() {
150        return this.entityId;
151    }
152
153    @Override
154    public String getEntityTypeCode() {
155        return this.entityTypeCode;
156    }
157
158    @Override
159    public CodedAttribute getPhoneType() {
160        return this.phoneType;
161    }
162
163    @Override
164    public String getPhoneNumber() {
165        return this.phoneNumber;
166    }
167
168    @Override
169    public String getExtensionNumber() {
170        return this.extensionNumber;
171    }
172
173    @Override
174    public String getCountryCode() {
175        return this.countryCode;
176    }
177
178    @Override
179    public String getPhoneNumberUnmasked() {
180        return this.phoneNumberUnmasked;
181    }
182
183    @Override
184    public String getExtensionNumberUnmasked() {
185        return this.extensionNumberUnmasked;
186    }
187
188    @Override
189    public String getCountryCodeUnmasked() {
190        return this.countryCodeUnmasked;
191    }
192
193    @Override
194    public String getFormattedPhoneNumber() {
195        return this.formattedPhoneNumber;
196    }
197
198    @Override
199    public String getFormattedPhoneNumberUnmasked() {
200        return this.formattedPhoneNumberUnmasked;
201    }
202
203    @Override
204    public boolean isSuppressPhone() {
205        return this.suppressPhone;
206    }
207
208    @Override
209    public boolean isDefaultValue() {
210        return this.defaultValue;
211    }
212
213    @Override
214    public Long getVersionNumber() {
215        return this.versionNumber;
216    }
217
218    @Override
219    public String getObjectId() {
220        return this.objectId;
221    }
222
223    @Override
224    public boolean isActive() {
225        return this.active;
226    }
227
228    /**
229     * A builder which can be used to construct {@link EntityPhone} instances.  Enforces the constraints of the {@link EntityPhoneContract}.
230     *
231     */
232    public final static class Builder
233        implements Serializable, ModelBuilder, EntityPhoneContract
234    {
235
236        private String id;
237        private String entityId;
238        private String entityTypeCode;
239        private CodedAttribute.Builder phoneType;
240        //private String phoneNumber;
241        //private String extensionNumber;
242        //private String countryCode;
243        private String phoneNumberUnmasked;
244        private String extensionNumberUnmasked;
245        private String countryCodeUnmasked;
246        //private String formattedPhoneNumber;
247        //private String formattedPhoneNumberUnmasked;
248        private boolean suppressPhone;
249        private boolean defaultValue;
250        private Long versionNumber;
251        private String objectId;
252        private boolean active;
253
254        private Builder() {
255
256        }
257
258        public static Builder create() {
259            return new Builder();
260        }
261
262        public static Builder create(EntityPhoneContract contract) {
263            if (contract == null) {
264                throw new IllegalArgumentException("contract was null");
265            }
266            Builder builder = create();
267            builder.setId(contract.getId());
268            builder.setEntityId(contract.getEntityId());
269            builder.setEntityTypeCode(contract.getEntityTypeCode());
270            builder.setSuppressPhone(contract.isSuppressPhone());
271            if (contract.getPhoneType() != null) {
272                builder.setPhoneType(CodedAttribute.Builder.create(contract.getPhoneType()));
273            }
274            builder.setPhoneNumber(contract.getPhoneNumberUnmasked());
275            builder.setExtensionNumber(contract.getExtensionNumberUnmasked());
276            builder.setCountryCode(contract.getCountryCodeUnmasked());
277            builder.setDefaultValue(contract.isDefaultValue());
278            builder.setVersionNumber(contract.getVersionNumber());
279            builder.setObjectId(contract.getObjectId());
280            builder.setActive(contract.isActive());
281            return builder;
282        }
283
284        public EntityPhone build() {
285            return new EntityPhone(this);
286        }
287
288        @Override
289        public String getId() {
290            return this.id;
291        }
292
293        @Override
294        public String getEntityTypeCode() {
295            return this.entityTypeCode;
296        }
297
298        @Override
299        public String getEntityId() {
300            return this.entityId;
301        }
302
303        @Override
304        public CodedAttribute.Builder getPhoneType() {
305            return this.phoneType;
306        }
307
308        @Override
309        public String getPhoneNumber() {
310            if (isSuppressPhone()) {
311                return KimApiConstants.RestrictedMasks.RESTRICTED_DATA_MASK_PHONE;
312            }
313            return this.phoneNumberUnmasked;
314        }
315
316        @Override
317        public String getExtensionNumber() {
318            if (isSuppressPhone()) {
319                return KimApiConstants.RestrictedMasks.RESTRICTED_DATA_MASK;
320            }
321            return this.extensionNumberUnmasked;
322        }
323
324        @Override
325        public String getCountryCode() {
326            if (isSuppressPhone()) {
327                return KimApiConstants.RestrictedMasks.RESTRICTED_DATA_MASK_CODE;
328            }
329            return this.countryCodeUnmasked;
330        }
331
332        @Override
333        public String getPhoneNumberUnmasked() {
334            return this.phoneNumberUnmasked;
335        }
336
337        @Override
338        public String getExtensionNumberUnmasked() {
339            return this.extensionNumberUnmasked;
340        }
341
342        @Override
343        public String getCountryCodeUnmasked() {
344            return this.countryCodeUnmasked;
345        }
346
347        @Override
348        public String getFormattedPhoneNumber() {
349            if (isSuppressPhone()) {
350                return KimApiConstants.RestrictedMasks.RESTRICTED_DATA_MASK;
351            }
352            return this.getFormattedPhoneNumberUnmasked();
353        }
354
355        @Override
356        public String getFormattedPhoneNumberUnmasked() {
357            StringBuffer sb = new StringBuffer( 30 );
358
359            // TODO: get extension from country code table
360            // TODO: append "+xxx" if country is not the default country
361            sb.append( this.phoneNumberUnmasked );
362            if ( StringUtils.isNotBlank( this.extensionNumberUnmasked) ) {
363                sb.append( " x" );
364                sb.append( this.extensionNumberUnmasked );
365            }
366
367            return sb.toString();
368        }
369
370        @Override
371        public boolean isSuppressPhone() {
372            return this.suppressPhone;
373        }
374
375        @Override
376        public boolean isDefaultValue() {
377            return this.defaultValue;
378        }
379
380        @Override
381        public Long getVersionNumber() {
382            return this.versionNumber;
383        }
384
385        @Override
386        public String getObjectId() {
387            return this.objectId;
388        }
389
390        @Override
391        public boolean isActive() {
392            return this.active;
393        }
394
395        public void setId(String id) {
396            if (StringUtils.isWhitespace(id)) {
397                throw new IllegalArgumentException("id is blank");
398            }
399            this.id = id;
400        }
401
402        public void setEntityTypeCode(String entityTypeCode) {
403            this.entityTypeCode = entityTypeCode;
404        }
405
406        public void setEntityId(String entityId) {
407            this.entityId = entityId;
408        }
409
410        public void setPhoneType(CodedAttribute.Builder phoneType) {
411            this.phoneType = phoneType;
412        }
413
414        public void setPhoneNumber(String phoneNumber) {
415            this.phoneNumberUnmasked = phoneNumber;
416        }
417
418        public void setExtensionNumber(String extensionNumber) {
419            this.extensionNumberUnmasked = extensionNumber;
420        }
421
422        public void setCountryCode(String countryCode) {
423            this.countryCodeUnmasked = countryCode;
424        }
425
426        private void setSuppressPhone(boolean suppressPhone) {
427            this.suppressPhone = suppressPhone;
428        }
429
430        public void setDefaultValue(boolean defaultValue) {
431            this.defaultValue = defaultValue;
432        }
433
434        public void setVersionNumber(Long versionNumber) {
435            this.versionNumber = versionNumber;
436        }
437
438        public void setObjectId(String objectId) {
439            this.objectId = objectId;
440        }
441
442        public void setActive(boolean active) {
443            this.active = active;
444        }
445
446    }
447
448
449    /**
450     * Defines some internal constants used on this class.
451     *
452     */
453    static class Constants {
454
455        final static String ROOT_ELEMENT_NAME = "entityPhone";
456        final static String TYPE_NAME = "EntityPhoneType";
457    }
458
459
460    /**
461     * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
462     *
463     */
464    static class Elements {
465
466        final static String ID = "id";
467        final static String ENTITY_TYPE_CODE = "entityTypeCode";
468        final static String ENTITY_ID = "entityId";
469        final static String PHONE_TYPE = "phoneType";
470        final static String PHONE_NUMBER = "phoneNumber";
471        final static String EXTENSION_NUMBER = "extensionNumber";
472        final static String COUNTRY_CODE = "countryCode";
473        final static String PHONE_NUMBER_UNMASKED = "phoneNumberUnmasked";
474        final static String EXTENSION_NUMBER_UNMASKED = "extensionNumberUnmasked";
475        final static String COUNTRY_CODE_UNMASKED = "countryCodeUnmasked";
476        final static String FORMATTED_PHONE_NUMBER = "formattedPhoneNumber";
477        final static String FORMATTED_PHONE_NUMBER_UNMASKED = "formattedPhoneNumberUnmasked";
478        final static String SUPPRESS_PHONE = "suppressPhone";
479        final static String DEFAULT_VALUE = "defaultValue";
480        final static String ACTIVE = "active";
481
482    }
483
484}