001/**
002 * Copyright 2005-2016 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.name;
017
018import java.io.Serializable;
019import java.text.SimpleDateFormat;
020import java.util.Collection;
021import java.util.Date;
022import javax.xml.bind.annotation.XmlAccessType;
023import javax.xml.bind.annotation.XmlAccessorType;
024import javax.xml.bind.annotation.XmlAnyElement;
025import javax.xml.bind.annotation.XmlElement;
026import javax.xml.bind.annotation.XmlRootElement;
027import javax.xml.bind.annotation.XmlSchemaType;
028import javax.xml.bind.annotation.XmlType;
029import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
030
031import org.apache.commons.lang.StringUtils;
032import org.joda.time.DateTime;
033import org.kuali.rice.core.api.CoreConstants;
034import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
035import org.kuali.rice.core.api.mo.ModelBuilder;
036import org.kuali.rice.kim.api.KimConstants;
037import org.kuali.rice.kim.api.identity.CodedAttribute;
038import org.kuali.rice.core.api.util.jaxb.DateTimeAdapter;
039import org.w3c.dom.Element;
040
041import javax.xml.bind.annotation.XmlAccessType;
042import javax.xml.bind.annotation.XmlAccessorType;
043import javax.xml.bind.annotation.XmlAnyElement;
044import javax.xml.bind.annotation.XmlElement;
045import javax.xml.bind.annotation.XmlRootElement;
046import javax.xml.bind.annotation.XmlType;
047import java.io.Serializable;
048import java.util.Collection;
049
050@XmlRootElement(name = EntityName.Constants.ROOT_ELEMENT_NAME)
051@XmlAccessorType(XmlAccessType.NONE)
052@XmlType(name = EntityName.Constants.TYPE_NAME, propOrder = {
053    EntityName.Elements.ID,
054    EntityName.Elements.ENTITY_ID,
055    EntityName.Elements.NAME_TYPE,
056    EntityName.Elements.NAME_PREFIX,
057    EntityName.Elements.NAME_TITLE,
058    EntityName.Elements.FIRST_NAME,
059    EntityName.Elements.MIDDLE_NAME,
060    EntityName.Elements.LAST_NAME,
061    EntityName.Elements.NAME_SUFFIX,
062    EntityName.Elements.COMPOSITE_NAME,
063    EntityName.Elements.NAME_PREFIX_UNMASKED,
064    EntityName.Elements.NAME_TITLE_UNMASKED,
065    EntityName.Elements.FIRST_NAME_UNMASKED,
066    EntityName.Elements.MIDDLE_NAME_UNMASKED,
067    EntityName.Elements.LAST_NAME_UNMASKED,
068    EntityName.Elements.NAME_SUFFIX_UNMASKED,
069    EntityName.Elements.COMPOSITE_NAME_UNMASKED,
070    EntityName.Elements.NOTE_MESSAGE,
071    EntityName.Elements.NAME_CHANGED_DATE,
072    EntityName.Elements.SUPPRESS_NAME,
073    EntityName.Elements.DEFAULT_VALUE,
074    EntityName.Elements.ACTIVE,
075    CoreConstants.CommonElements.VERSION_NUMBER,
076    CoreConstants.CommonElements.OBJECT_ID,
077    CoreConstants.CommonElements.FUTURE_ELEMENTS
078})
079public final class EntityName extends AbstractDataTransferObject
080    implements EntityNameContract
081{
082
083    @XmlElement(name = Elements.NAME_SUFFIX, required = false)
084    private final String nameSuffix;
085    @XmlElement(name = Elements.ENTITY_ID, required = false)
086    private final String entityId;
087    @XmlElement(name = Elements.NAME_TYPE, required = false)
088    private final CodedAttribute nameType;
089    @XmlElement(name = Elements.FIRST_NAME, required = false)
090    private final String firstName;
091    @XmlElement(name = Elements.FIRST_NAME_UNMASKED, required = false)
092    private final String firstNameUnmasked;
093    @XmlElement(name = Elements.MIDDLE_NAME, required = false)
094    private final String middleName;
095    @XmlElement(name = Elements.MIDDLE_NAME_UNMASKED, required = false)
096    private final String middleNameUnmasked;
097    @XmlElement(name = Elements.LAST_NAME, required = false)
098    private final String lastName;
099    @XmlElement(name = Elements.LAST_NAME_UNMASKED, required = false)
100    private final String lastNameUnmasked;
101    @XmlElement(name = Elements.NAME_PREFIX, required = false)
102    private final String namePrefix;
103    @XmlElement(name = Elements.NAME_PREFIX_UNMASKED, required = false)
104    private final String namePrefixUnmasked;
105    @XmlElement(name = Elements.NAME_TITLE, required = false)
106    private final String nameTitle;
107    @XmlElement(name = Elements.NAME_TITLE_UNMASKED, required = false)
108    private final String nameTitleUnmasked;
109    @XmlElement(name = Elements.NAME_SUFFIX_UNMASKED, required = false)
110    private final String nameSuffixUnmasked;
111    @XmlElement(name = Elements.COMPOSITE_NAME, required = false)
112    private final String compositeName;
113    @XmlElement(name = Elements.COMPOSITE_NAME_UNMASKED, required = false)
114    private final String compositeNameUnmasked;
115    @XmlElement(name = Elements.NOTE_MESSAGE, required = false)
116    private final String noteMessage;
117    @XmlElement(name = Elements.NAME_CHANGED_DATE, required = false)
118    @XmlJavaTypeAdapter(DateTimeAdapter.class)
119    private final DateTime nameChangedDate;
120    @XmlElement(name = Elements.SUPPRESS_NAME, required = false)
121    private final boolean suppressName;
122    @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
123    private final Long versionNumber;
124    @XmlElement(name = CoreConstants.CommonElements.OBJECT_ID, required = false)
125    private final String objectId;
126    @XmlElement(name = Elements.DEFAULT_VALUE, required = false)
127    private final boolean defaultValue;
128    @XmlElement(name = Elements.ACTIVE, required = false)
129    private final boolean active;
130    @XmlElement(name = Elements.ID, required = false)
131    private final String id;
132    @SuppressWarnings("unused")
133    @XmlAnyElement
134    private final Collection<Element> _futureElements = null;
135
136    /**
137     * Private constructor used only by JAXB.
138     * 
139     */
140    private EntityName() {
141        this.nameSuffix = null;
142        this.entityId = null;
143        this.nameType = null;
144        this.firstName = null;
145        this.firstNameUnmasked = null;
146        this.middleName = null;
147        this.middleNameUnmasked = null;
148        this.lastName = null;
149        this.lastNameUnmasked = null;
150        this.namePrefix = null;
151        this.namePrefixUnmasked = null;
152        this.nameTitle = null;
153        this.nameTitleUnmasked = null;
154        this.nameSuffixUnmasked = null;
155        this.compositeName = null;
156        this.compositeNameUnmasked = null;
157        this.noteMessage = null;
158        this.nameChangedDate = null;
159        this.suppressName = false;
160        this.versionNumber = null;
161        this.objectId = null;
162        this.defaultValue = false;
163        this.active = false;
164        this.id = null;
165    }
166
167    private EntityName(Builder builder) {
168        this.nameSuffix = builder.getNameSuffix();
169        this.entityId = builder.getEntityId();
170        this.nameType = builder.getNameType() != null ? builder.getNameType().build() : null;
171        this.firstName = builder.getFirstName();
172        this.firstNameUnmasked = builder.getFirstNameUnmasked();
173        this.middleName = builder.getMiddleName();
174        this.middleNameUnmasked = builder.getMiddleNameUnmasked();
175        this.lastName = builder.getLastName();
176        this.lastNameUnmasked = builder.getLastNameUnmasked();
177        this.namePrefix = builder.getNamePrefix();
178        this.namePrefixUnmasked = builder.getNamePrefixUnmasked();
179        this.nameTitle = builder.getNameTitle();
180        this.nameTitleUnmasked = builder.getNameTitleUnmasked();
181        this.nameSuffixUnmasked = builder.getNameSuffixUnmasked();
182        this.compositeName = builder.getCompositeName();
183        this.compositeNameUnmasked = builder.getCompositeNameUnmasked();
184        this.noteMessage = builder.getNoteMessage();
185        this.nameChangedDate = builder.getNameChangedDate();
186        this.suppressName = builder.isSuppressName();
187        this.versionNumber = builder.getVersionNumber();
188        this.objectId = builder.getObjectId();
189        this.defaultValue = builder.isDefaultValue();
190        this.active = builder.isActive();
191        this.id = builder.getId();
192    }
193
194    @Override
195    public String getNameSuffix() {
196        return this.nameSuffix;
197    }
198
199    @Override
200    public String getEntityId() {
201        return this.entityId;
202    }
203
204    @Override
205    public CodedAttribute getNameType() {
206        return this.nameType;
207    }
208
209    @Override
210    public String getFirstName() {
211        return this.firstName;
212    }
213
214    @Override
215    public String getFirstNameUnmasked() {
216        return this.firstNameUnmasked;
217    }
218
219    @Override
220    public String getMiddleName() {
221        return this.middleName;
222    }
223
224    @Override
225    public String getMiddleNameUnmasked() {
226        return this.middleNameUnmasked;
227    }
228
229    @Override
230    public String getLastName() {
231        return this.lastName;
232    }
233
234    @Override
235    public String getLastNameUnmasked() {
236        return this.lastNameUnmasked;
237    }
238
239    @Override
240    public String getNamePrefix() {
241        return this.namePrefix;
242    }
243
244    @Override
245    public String getNamePrefixUnmasked() {
246        return this.namePrefixUnmasked;
247    }
248
249    @Override
250    public String getNameTitle() {
251        return this.nameTitle;
252    }
253
254    @Override
255    public String getNameTitleUnmasked() {
256        return this.nameTitleUnmasked;
257    }
258
259    @Override
260    public String getNameSuffixUnmasked() {
261        return this.nameSuffixUnmasked;
262    }
263
264    @Override
265    public String getCompositeName() {
266        return this.compositeName;
267    }
268
269    @Override
270    public String getCompositeNameUnmasked() {
271        return this.compositeNameUnmasked;
272    }
273
274    @Override
275    public String getNoteMessage() {
276        return this.noteMessage;
277    }
278
279    @Override
280    public DateTime getNameChangedDate() {
281        return this.nameChangedDate;
282    }
283
284    @Override
285    public boolean isSuppressName() {
286        return this.suppressName;
287    }
288
289    @Override
290    public Long getVersionNumber() {
291        return this.versionNumber;
292    }
293
294    @Override
295    public String getObjectId() {
296        return this.objectId;
297    }
298
299    @Override
300    public boolean isDefaultValue() {
301        return this.defaultValue;
302    }
303
304    @Override
305    public boolean isActive() {
306        return this.active;
307    }
308
309    @Override
310    public String getId() {
311        return this.id;
312    }
313
314
315    /**
316     * A builder which can be used to construct {@link EntityName} instances.  Enforces the constraints of the {@link EntityNameContract}.
317     * 
318     */
319    public final static class Builder
320        implements Serializable, ModelBuilder, EntityNameContract
321    {
322
323        private String nameSuffix;
324        private String entityId;
325        private CodedAttribute.Builder nameType;
326        private String firstName;
327        private String middleName;
328        private String lastName;
329        private String namePrefix;
330        private String nameTitle;
331        private String compositeName;
332        private String noteMessage;
333        private DateTime nameChangedDate;
334        private boolean suppressName;
335        private Long versionNumber;
336        private String objectId;
337        private boolean defaultValue;
338        private boolean active;
339        private String id;
340
341        private Builder() { }
342
343        private Builder(String id, String entityId, String firstName, String lastName, boolean suppressName) {
344            setId(id);
345            setEntityId(entityId);
346            setFirstName(firstName);
347            setLastName(lastName);
348            setSuppressName(suppressName);
349        }
350
351        public static Builder create() {
352            return new Builder();
353        }
354
355        public static Builder create(String id, String entityId, String firstName,
356                                                             String lastName, boolean suppressName) {
357                        return new Builder(id, entityId, firstName, lastName, suppressName);
358        }
359
360        public static Builder create(EntityNameContract contract) {
361            if (contract == null) {
362                throw new IllegalArgumentException("contract was null");
363            }
364            Builder builder = create();
365            builder.setNameSuffix(contract.getNameSuffix());
366            builder.setEntityId(contract.getEntityId());
367            if (contract.getNameType() != null) {
368                builder.setNameType(CodedAttribute.Builder.create(contract.getNameType()));
369            }
370            builder.setFirstName(contract.getFirstName());
371            builder.setMiddleName(contract.getMiddleName());
372            builder.setLastName(contract.getLastName());
373            builder.setNamePrefix(contract.getNamePrefix());
374            builder.setNameTitle(contract.getNameTitle());
375            builder.setNoteMessage(contract.getNoteMessage());
376            builder.setNameChangedDate(contract.getNameChangedDate());
377            builder.setSuppressName(contract.isSuppressName());
378            builder.setVersionNumber(contract.getVersionNumber());
379            builder.setObjectId(contract.getObjectId());
380            builder.setDefaultValue(contract.isDefaultValue());
381            builder.setActive(contract.isActive());
382            builder.setId(contract.getId());
383            builder.setCompositeName(contract.getCompositeName());
384            return builder;
385        }
386
387        public EntityName build() {
388            return new EntityName(this);
389        }
390
391        @Override
392        public String getNameSuffix() {
393            if (isSuppressName()) {
394                return KimConstants.RESTRICTED_DATA_MASK;
395            }
396            return this.nameSuffix;
397        }
398
399        @Override
400        public String getEntityId() {
401            return this.entityId;
402        }
403
404        @Override
405        public CodedAttribute.Builder getNameType() {
406            return this.nameType;
407        }
408
409        @Override
410        public String getFirstName() {
411            if (isSuppressName()) {
412                return KimConstants.RESTRICTED_DATA_MASK;
413            }
414            return this.firstName;
415        }
416
417        @Override
418        public String getFirstNameUnmasked() {
419            return this.firstName;
420        }
421
422        @Override
423        public String getMiddleName() {
424            if (isSuppressName()) {
425                return KimConstants.RESTRICTED_DATA_MASK;
426            }
427            return this.middleName;
428        }
429
430        @Override
431        public String getMiddleNameUnmasked() {
432            return this.middleName;
433        }
434
435        @Override
436        public String getLastName() {
437            if (isSuppressName()) {
438                return KimConstants.RESTRICTED_DATA_MASK;
439            }
440            return this.lastName;
441        }
442
443        @Override
444        public String getLastNameUnmasked() {
445            return this.lastName;
446        }
447
448        @Override
449        public String getNamePrefix() {
450            if (isSuppressName()) {
451                return KimConstants.RESTRICTED_DATA_MASK;
452            }
453            return this.namePrefix;
454        }
455
456        @Override
457        public String getNamePrefixUnmasked() {
458            return this.namePrefix;
459        }
460
461        @Override
462        public String getNameTitle() {
463            if (isSuppressName()) {
464                return KimConstants.RESTRICTED_DATA_MASK;
465            }
466            return this.nameTitle;
467        }
468
469        @Override
470        public String getNameTitleUnmasked() {
471            return this.nameTitle;
472        }
473
474        @Override
475        public String getNameSuffixUnmasked() {
476            return this.nameSuffix;
477        }
478
479        @Override
480        public String getCompositeName() {
481            if (isSuppressName()) {
482                return KimConstants.RESTRICTED_DATA_MASK;
483            }
484            return getCompositeNameUnmasked();
485        }
486
487        @Override
488        public String getCompositeNameUnmasked() {
489                if(this.compositeName == null) {
490                //KULRICE-12360: Display name formatting issue when middle or first name missing
491                String lastNameTemp = "";
492                String firstNameTemp= "";
493
494                if (StringUtils.isNotBlank(getLastName())) {
495                    lastNameTemp = getLastName();
496                }
497                if (StringUtils.isNotBlank(getFirstName())) {
498                    firstNameTemp = getFirstName();
499                }
500                if (StringUtils.isNotBlank(lastNameTemp) && StringUtils.isNotBlank(firstNameTemp)) {
501                    lastNameTemp = lastNameTemp + ", ";
502                }
503
504                setCompositeName(lastNameTemp + firstNameTemp + (StringUtils.isBlank(getMiddleName()) ? "" : " " + getMiddleName()));
505                }
506            return this.compositeName;
507        }
508
509        @Override
510        public String getNoteMessage() {
511            return this.noteMessage;
512        }
513
514        @Override
515        public DateTime getNameChangedDate() {
516            return this.nameChangedDate;
517        }
518
519        @Override
520        public boolean isSuppressName() {
521            return this.suppressName;
522        }
523
524        @Override
525        public Long getVersionNumber() {
526            return this.versionNumber;
527        }
528
529        @Override
530        public String getObjectId() {
531            return this.objectId;
532        }
533
534        @Override
535        public boolean isDefaultValue() {
536            return this.defaultValue;
537        }
538
539        @Override
540        public boolean isActive() {
541            return this.active;
542        }
543
544        @Override
545        public String getId() {
546            return this.id;
547        }
548
549        public void setNameSuffix(String nameSuffix) {
550            this.nameSuffix = nameSuffix;
551        }
552
553        public void setEntityId(String entityId) {
554            this.entityId = entityId;
555        }
556
557        public void setNameType(CodedAttribute.Builder nameType) {
558            this.nameType = nameType;
559        }
560
561        public void setFirstName(String firstName) {
562            this.firstName = firstName;
563        }
564
565        public void setMiddleName(String middleName) {
566
567            this.middleName = middleName;
568        }
569
570        public void setLastName(String lastName) {
571            this.lastName = lastName;
572        }
573
574        public void setNamePrefix(String namePrefix) {
575            this.namePrefix = namePrefix;
576        }
577
578        public void setNameTitle(String nameTitle) {
579            this.nameTitle = nameTitle;
580        }
581
582        public void setCompositeName(String compositeName) {
583                this.compositeName = compositeName;
584        }
585        
586        public void setNoteMessage(String noteMessage) {
587            this.noteMessage = noteMessage;
588        }
589
590        public void setNameChangedDate(DateTime nameChangedDate) {
591            this.nameChangedDate = nameChangedDate;
592        }
593
594        private void setSuppressName(boolean suppressName) {
595            this.suppressName = suppressName;
596        }
597
598        public void setVersionNumber(Long versionNumber) {
599            this.versionNumber = versionNumber;
600        }
601
602        public void setObjectId(String objectId) {
603            this.objectId = objectId;
604        }
605
606        public void setDefaultValue(boolean defaultValue) {
607            this.defaultValue = defaultValue;
608        }
609
610        public void setActive(boolean active) {
611            this.active = active;
612        }
613
614        public void setId(String id) {
615            if (StringUtils.isWhitespace(id)) {
616                throw new IllegalArgumentException("id is blank");
617            }
618            this.id = id;
619        }
620
621    }
622
623
624    /**
625     * Defines some internal constants used on this class.
626     * 
627     */
628    static class Constants {
629
630        final static String ROOT_ELEMENT_NAME = "entityName";
631        final static String TYPE_NAME = "EntityNameType";
632    }
633
634
635    /**
636     * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
637     * 
638     */
639    static class Elements {
640
641        final static String NAME_SUFFIX = "nameSuffix";
642        final static String ENTITY_ID = "entityId";
643        final static String NAME_TYPE = "nameType";
644        final static String FIRST_NAME = "firstName";
645        final static String FIRST_NAME_UNMASKED = "firstNameUnmasked";
646        final static String MIDDLE_NAME = "middleName";
647        final static String MIDDLE_NAME_UNMASKED = "middleNameUnmasked";
648        final static String LAST_NAME = "lastName";
649        final static String LAST_NAME_UNMASKED = "lastNameUnmasked";
650        final static String NAME_PREFIX = "namePrefix";
651        final static String NAME_PREFIX_UNMASKED = "namePrefixUnmasked";
652        final static String NAME_TITLE = "nameTitle";
653        final static String NAME_TITLE_UNMASKED = "nameTitleUnmasked";
654        final static String NAME_SUFFIX_UNMASKED = "nameSuffixUnmasked";
655        final static String COMPOSITE_NAME = "compositeName";
656        final static String COMPOSITE_NAME_UNMASKED = "compositeNameUnmasked";
657        final static String NOTE_MESSAGE = "noteMessage";
658        final static String NAME_CHANGED_DATE= "nameChangedDate";
659        final static String SUPPRESS_NAME = "suppressName";
660        final static String DEFAULT_VALUE = "defaultValue";
661        final static String ACTIVE = "active";
662        final static String ID = "id";
663
664    }
665
666}