View Javadoc
1   /*
2    * Copyright (C) 2003-2007 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.social.core.identity.model;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.exoplatform.social.core.chromattic.entity.ActivityProfileEntity;
27  import org.exoplatform.social.core.model.AvatarAttachment;
28  import org.exoplatform.social.core.profile.ProfileLifeCycle;
29  
30  /**
31   * The Class Profile.
32   */
33  public class Profile {
34  
35    /** gender key. */
36    public static final String        GENDER         = "gender";
37    public static final String        MALE           = "male";
38    public static final String        FEMALE         = "female";
39  
40    /** username key. */
41    public static final String        USERNAME       = "username";
42  
43    /** firstname key. */
44    public static final String        FIRST_NAME     = "firstName";
45  
46    /** lastname key. */
47    public static final String        LAST_NAME      = "lastName";
48  
49    /** lastname key. */
50    public static final String        FULL_NAME      = "fullName";
51    
52    /** email key. */
53    public static final String        EMAIL          = "email";
54  
55    /** email key. */
56    public static final String        ABOUT_ME       = "aboutMe";
57  
58    /** profile of a deleted user */
59    public static final String        DELETED        = "deleted";
60  
61    /**
62     * property of type {@link AvatarAttachment} that contains the avatar
63     */
64    public static final String        AVATAR         = "avatar";
65  
66    public static final String        BANNER         = "banner";
67    
68    /** EXPERIENCE. */
69    public static final String        EXPERIENCES    = "experiences";
70  
71    /** ID. */
72    public static final String        EXPERIENCES_ID          = "id";
73  
74    /** COMPANY. */
75    public static final String        EXPERIENCES_COMPANY     = "company";
76  
77    /** POSITION. */
78    public static final String        EXPERIENCES_POSITION    = "position";
79  
80    /** POSITION. */
81    public static final String        EXPERIENCES_SKILLS      = "skills";
82  
83    /** START DATE OF EXPERIENCE. */
84    public static final String        EXPERIENCES_START_DATE  = "startDate";
85  
86    /** END DATE OF EXPERIENCE. */
87    public static final String        EXPERIENCES_END_DATE    = "endDate";
88  
89    /** CURRENT OR PAST EXPERIENCE. */
90    public static final String        EXPERIENCES_IS_CURRENT  = "isCurrent";
91  
92    /** DESCRIPTION OF EXPERIENCE. */
93    public static final String        EXPERIENCES_DESCRIPTION = "description";
94  
95    /** POSITION. */
96    public static final String        POSITION       = "position";
97  
98    /**
99     * An optional url for this profile
100    */
101   @Deprecated
102   public static final String        URL            = "Url";
103 
104   /** PHONES key. */
105   public static final String        CONTACT_PHONES = "phones";
106 
107   /** IMS key. */
108   public static final String        CONTACT_IMS    = "ims";
109 
110   /** URLS key. */
111   public static final String        CONTACT_URLS   = "urls";
112 
113   /** url postfix */
114   public static final String        URL_POSTFIX    = "Url";
115 
116   /** Resized subfix */
117   public static final String        RESIZED_SUBFIX = "RESIZED_";
118 
119   /** Space string */
120   private static final String       SPACE_STR = " ";
121   
122   /** Types of updating of profile. */
123   public static enum                UpdateType 
124                                       {
125                                         POSITION,
126                                         BASIC_INFOR,
127                                         CONTACT,
128                                         EXPERIENCES,
129                                         AVATAR,
130                                         ABOUT_ME,
131                                         BANNER;
132                                         
133                                         public void updateActivity(ProfileLifeCycle profileLifeCycle, Profile profile) {
134                                           switch (this) {
135                                             case ABOUT_ME: {
136                                               profileLifeCycle.aboutMeUpdated(profile.getIdentity().remoteId, profile);
137                                               break;
138                                             }
139                                             case CONTACT: {
140                                               profileLifeCycle.contactUpdated(profile.getIdentity().getRemoteId(), profile);
141                                               break;
142                                             }
143                                             case EXPERIENCES: {
144                                               profileLifeCycle.experienceUpdated(profile.getIdentity().getRemoteId(), profile);
145                                               break;
146                                             }
147                                             case AVATAR: {
148                                               profileLifeCycle.avatarUpdated(profile.getIdentity().getRemoteId(), profile);
149                                               break;
150                                             }
151                                             case BANNER: {
152                                               profileLifeCycle.bannerUpdated(profile.getIdentity().getRemoteId(), profile);
153                                               break;
154                                             }
155                                             default :
156                                               break;
157                                           }
158                                         }
159                                       };
160                                       
161   public static enum                AttachedActivityType
162                                       {
163                                         USER("userProfileActivityId"),
164                                         SPACE("spaceProfileActivityId"),
165                                         RELATION("relationActivityId"),
166                                         RELATIONSHIP("relationShipActivityId");
167                                         
168                                         private String type;
169                                         private AttachedActivityType(String type) {
170                                           this.type = type;
171                                         }
172                                         public String value() {
173                                           return this.type;
174                                         }
175                                         public void setActivityId(ActivityProfileEntity entity, String activityId) {
176                                           switch (this) {
177                                             case USER: {
178                                               entity.setUserProfileActivityId(activityId);
179                                               break;
180                                             }
181                                             case SPACE: {
182                                               entity.setSpaceProfileActivityId(activityId);
183                                               break;
184                                             }
185                                             case RELATION: {
186                                               entity.setRelationActivityId(activityId);
187                                               break;
188                                             }
189                                             case RELATIONSHIP: {
190                                               entity.setRelationShipActivityId(activityId);
191                                               break;
192                                             }
193                                             default :
194                                               break;
195                                           }
196                                         }
197                                         public String getActivityId(ActivityProfileEntity entity) {
198                                           switch (this) {
199                                           case USER: {
200                                             return entity.getUserProfileActivityId();
201                                           }
202                                           case SPACE: {
203                                             return entity.getSpaceProfileActivityId();
204                                           }
205                                           case RELATION: {
206                                             return entity.getRelationActivityId();
207                                           }
208                                           case RELATIONSHIP: {
209                                             return entity.getRelationShipActivityId();
210                                           }
211                                           default : {
212                                             return null;
213                                           }
214                                         }
215                                         }
216                                       };
217   
218                                       
219   /** The properties. */
220   private final Map<String, Object> properties     = new HashMap<String, Object>();
221 
222   private static final Map<UpdateType, String[]> updateTypes = new HashMap<UpdateType, String[]>();
223   static {
224     updateTypes.put(UpdateType.POSITION, new String[] {POSITION});
225     updateTypes.put(UpdateType.BASIC_INFOR, new String[] {FIRST_NAME, LAST_NAME, EMAIL});
226     updateTypes.put(UpdateType.CONTACT, new String[] {GENDER, CONTACT_PHONES, CONTACT_IMS, CONTACT_URLS});
227     updateTypes.put(UpdateType.EXPERIENCES, new String[] {EXPERIENCES});
228     updateTypes.put(UpdateType.AVATAR, new String[] {AVATAR});
229     updateTypes.put(UpdateType.BANNER, new String[] {BANNER});
230   }
231 
232   /** The identity. */
233   private final Identity            identity;
234 
235   /** The id. */
236   private String                    id;
237 
238   /** The last loaded time */
239   private long                      lastLoaded;
240 
241   /** Indicates whether or not the profile has been modified locally */
242   private boolean                   hasChanged;
243 
244   /** Indicates the type of profile are being modified locally */
245   private UpdateType                updateType;
246 
247   /** Profile url, this will never be stored */
248   private String                    url;
249 
250   /** Profile url, this will never be stored */
251   private String                    avatarUrl;
252 
253   /** Profile url, this will never be stored */
254   private String                    bannerUrl;
255 
256   private AttachedActivityType      attachedActivityType;
257   
258   /** Profile created time **/
259   private long                      createdTime;
260   
261   private List<UpdateType> listUpdateTypes;
262   
263   /**  The last updated time of avatar ( in millisecond) */
264   private Long                      avatarLastUpdated;
265 
266   /**  The last updated time of avatar ( in millisecond) */
267   private Long                      bannerLastUpdated;
268   
269   /**
270    * Instantiates a new profile.
271    *
272    * @param identity the identity
273    */
274   public Profile(final Identity identity) {
275     this.identity = identity;
276   }
277 
278   /**
279    * Gets the identity.
280    *
281    * @return the identity
282    */
283   public final Identity getIdentity() {
284     return identity;
285   }
286 
287   /**
288    * Gets the id.
289    *
290    * @return the id
291    */
292   public final String getId() {
293     return id;
294   }
295 
296   /**
297    * Sets the id.
298    *
299    * @param id the new id
300    */
301   public final void setId(final String id) {
302     this.id = id;
303   }
304 
305   /**
306    * Gets the last loaded time.
307    *
308    * @return the last loaded time
309    */
310   public final long getLastLoaded() {
311     return lastLoaded;
312   }
313 
314   /**
315    * Sets the last loaded time.
316    *
317    * @param lastLoaded the new last loaded time
318    */
319   public final void setLastLoaded(final long lastLoaded) {
320     this.lastLoaded = lastLoaded;
321   }
322 
323   /**
324    * Indicates whether or not the profile has been modified locally.
325    *
326    * @return <code>true</code> if it has been modified locally, <code>false</code> otherwise.
327    */
328   public final boolean hasChanged() {
329     return hasChanged;
330   }
331 
332   /**
333    * Clear the has changed flag.
334    */
335   public final void clearHasChanged() {
336      setHasChanged(false);
337   }
338 
339   /**
340    * Gets type of update.
341    * @return the updated type for a profile
342    * @since 1.2.0-GA
343    */
344   public UpdateType getUpdateType() {
345     return updateType;
346   }
347 
348   public AttachedActivityType getAttachedActivityType() {
349     return attachedActivityType;
350   }
351 
352   public void setAttachedActivityType(AttachedActivityType attachedActivityType) {
353     this.attachedActivityType = attachedActivityType;
354   }
355 
356   /**
357    * Sets type of update.
358    * 
359    * @param updateType
360    * @since 1.2.0-GA
361    */
362   protected void setUpdateType(String updateType) {
363     for (UpdateType key : updateTypes.keySet()) {
364       String[] updateTypeValues = updateTypes.get(key);
365       for (String value : updateTypeValues) {
366         if(value.equals(updateType)) {
367           this.updateType = key;
368           break;
369         }
370       }
371     }
372   }
373 
374   /**
375    * Sets the value of the property <code>hasChanged<code>.
376    *
377    * @param hasChanged the new hasChanged
378    */
379   private void setHasChanged(final boolean hasChanged) {
380     this.hasChanged = hasChanged;
381   }
382 
383   /**
384    * Gets the property.
385    *
386    * @param name the name
387    * @return the property
388    */
389   public final Object getProperty(final String name) {
390 
391     // TODO : remove with Profile.URL
392     if (URL.equals(name)) {
393       return this.url;
394     }
395     
396     return properties.get(name);
397   }
398 
399   /**
400    * Sets the property.
401    *
402    * @param name the name
403    * @param value the value
404    */
405   public final void setProperty(final String name, final Object value) {
406 
407     // TODO : remove with Profile.URL
408     if (URL.equals(name)) {
409       this.url = value.toString();
410       return;
411     }
412     
413     properties.put(name, value);
414     setHasChanged(true);
415     setUpdateType(name);
416 
417   }
418 
419   /**
420    * Contains.
421    *
422    * @param name the name
423    * @return true, if successful
424    */
425   public final boolean contains(final String name) {
426     return properties.containsKey(name);
427   }
428 
429   /**
430    * Gets the properties.
431    *
432    * @return the properties
433    */
434   public final Map<String, Object> getProperties() {
435     return properties;
436   }
437 
438   /**
439    * Removes the property.
440    *
441    * @param name the name
442    */
443   public final void removeProperty(final String name) {
444     properties.remove(name);
445     setHasChanged(true);
446   }
447 
448   /**
449    * Gets the property value.
450    *
451    * @param name the name
452    * @return the property value
453    * @deprecated use {@link #getProperty(String)}. Will be removed at 1.3.x
454    * @return
455    */
456   public final Object getPropertyValue(final String name) {
457     return getProperty(name);
458   }
459 
460   /**
461    * Gets the full name.
462    *
463    * @return the full name
464    */
465   public final String getFullName() {
466     String fullName = (String) getProperty(FULL_NAME);
467     if (fullName != null && fullName.length() > 0) {
468       return fullName;
469     }
470     
471     String firstName = (String) getProperty(FIRST_NAME);
472     String lastName = (String) getProperty(LAST_NAME);
473     fullName = (firstName != null) ? firstName : StringUtils.EMPTY;
474     fullName += (lastName != null) ? SPACE_STR + lastName : StringUtils.EMPTY;
475     return fullName;
476   }
477   
478   /**
479    * Get this profile URL
480    * 
481    * @return this profile URL
482    */
483   public final String getUrl() {
484     return url;
485   }
486 
487   /**
488    * Set this profile URL
489    */
490   public void setUrl(final String url) {
491     this.url = url;
492   }
493 
494 
495   /**
496    * Gets email address of this profile.
497    * 
498    * @return email in String format
499    */
500   public final String getEmail() {
501     return (String) getProperty(EMAIL);
502   }
503   
504   /**
505    * Add or modify properties of the profile
506    * 
507    * @param props
508    */
509   public final void addOrModifyProperties(final Map<String, Object> props) {
510     Iterator<Map.Entry<String, Object>> it = props.entrySet().iterator();
511     while (it.hasNext()) {
512       Map.Entry<String, Object> entry = it.next();
513       String key = entry.getKey();
514       // we skip all the property that are jcr related
515       if (key.contains(":")) {
516         continue;
517       }
518       setProperty(key, entry.getValue());
519     }
520     setHasChanged(true);
521   }
522 
523   /**
524    * Gets avatar url
525    * 
526    * @return avatar image source
527    * @deprecated use {@link #getAvatarUrl()}. Will be removed at 1.3.x
528    */
529   @Deprecated
530   public final String getAvatarImageSource() {
531     return getAvatarUrl();
532   }
533 
534   /**
535    * Gets avatar url
536    * 
537    * @return avatar image source
538    * @since 1.2.0-GA
539    */
540   public final String getAvatarUrl() {
541     return avatarUrl;
542   }
543 
544   /**
545    * Sets avatar url
546    *
547    * @since 1.2.0-GA
548    */
549   public void setAvatarUrl(final String avatarUrl) {
550     this.avatarUrl = avatarUrl;
551   }
552 
553   /**
554    * Gets avatar url
555    *
556    * @return avatar image source
557    * @since 1.2.0-GA
558    */
559   public final String getBannerUrl() {
560     return bannerUrl;
561   }
562 
563   /**
564    * Sets avatar url
565    *
566    * @since 1.2.0-GA
567    */
568   public void setBannerUrl(final String bannerUrl) {
569     this.bannerUrl = bannerUrl;
570   }
571 
572   /**
573    * Gets position
574    * 
575    * @return position
576    * @since 1.2.0-GA
577    */
578   public final String getPosition() {
579     return (String) getProperty(Profile.POSITION);
580   }
581   
582   /**
583    * Gets gender
584    * 
585    * @return gender of user
586    * @since 4.0.0.Alpha1
587    */
588   public final String getGender() {
589     return (String) getProperty(Profile.GENDER);
590   }
591   
592   /**
593    * Gets Phones
594    * 
595    * @return list of user's number phone
596    * @since 4.0.0.Alpha1
597    */
598   public final List<Map<String, String>> getPhones() {
599     return (List<Map<String, String>>) getProperty(Profile.CONTACT_PHONES);
600   }
601 
602   public long getCreatedTime() {
603     return createdTime;
604   }
605 
606   public void setCreatedTime(Long createdTime) {
607     if (createdTime != null) {
608       this.createdTime = createdTime;
609     } else {
610       this.createdTime = System.currentTimeMillis();
611     }
612   }
613 
614   /*
615      * Get uuid, identity, properties of profile
616      * @see java.lang.Object#toString()
617      */
618   @Override
619   public final String toString() {
620     return "[uuid : " + id + " identity : " + identity.getId() + " properties: " + properties;
621   }
622 
623   public List<UpdateType> getListUpdateTypes() {
624     return listUpdateTypes != null ? listUpdateTypes : new ArrayList<UpdateType>();
625   }
626 
627   public void setListUpdateTypes(List<UpdateType> listUpdateTypes) {
628     this.listUpdateTypes = listUpdateTypes;
629   }
630   
631   /**
632    * Gets the last updated time in milliseconds of avatar in a profile
633    * @return {@link Void}
634    */
635   public Long getAvatarLastUpdated() {
636     return avatarLastUpdated;
637   }
638   
639   /**
640    * Sets the last updated time in milliseconds of avatar in a profile
641    * @param avatarLastUpdated
642    */
643   public void setAvatarLastUpdated(Long avatarLastUpdated) {
644     this.avatarLastUpdated = avatarLastUpdated;
645   }
646 
647   public Long getBannerLastUpdated() {
648     return bannerLastUpdated;
649   }
650 
651   public void setBannerLastUpdated(Long bannerLastUpdated) {
652     this.bannerLastUpdated = bannerLastUpdated;
653   }
654 }