1   package hudsonfog.voc.model;
2   
3   import com.fogx.webdav.DavResource;
4   import com.fogx.webdav.DavClass;
5   import com.fogx.webdav.DavBean;
6   import com.fogx.webdav.DavProperty;
7   import static com.fogx.webdav.DavProperty.*;
8   import com.fogx.webdav.packages.DavBeanPackage;
9   import com.fogx.webdav.util.DavResourceSupport;
10  import com.fogx.webdav.util.UrlUtil;
11  import java.util.Date;
12  import java.util.Map;
13  import java.util.HashMap;
14  import java.util.List;
15  import java.util.Collections;
16  import java.util.Arrays;
17  
18  import hudsonfog.voc.aspects.ui.*;
19  import hudsonfog.voc.system.changeHistory.*;
20  import hudsonfog.voc.model.company.*;
21  import hudsonfog.voc.aspects.tags.*;
22  import hudsonfog.voc.system.primitiveTypes.*;
23  import hudsonfog.voc.system.behavior.*;
24  import hudsonfog.voc.model.recurrence.*;
25  import hudsonfog.voc.model.portal.*;
26  import hudsonfog.voc.system.parse.*;
27  import hudsonfog.voc.system.security.*;
28  import hudsonfog.voc.model.workflow.*;
29  import hudsonfog.voc.system.XMLSchema.*;
30  
31  import hudsonfog.voc.system.fog.*;
32  
33  
34  public abstract class portal {
35  
36    /**
37   * Any resource of a class that implements Annotated can be annotated with Comments.
38   * In addition - it can serve as a chat room.
39   */
40    public static interface Annotated extends Folder, FileSystem {
41           @_avoidModificationTracking
42           @_icon("icons/comment.gif")
43           @_notSearchable
44           @_backLink("forum")
45           @_subPropertyOf("folderItems")
46        @s public Note[]                        comments = null;
47           @_avoidModificationTracking
48           @_readOnly
49           @_notSearchable
50           @_avoidDisplaying
51           public Note                          lastComment = null;
52           @_readOnly
53           @_icon("icons/webchat.gif")
54           @_notSearchable
55           @_avoidDisplayingInControlPanel
56           @_backLink("forResource")
57           public ChatHistoryFile[]             chatHistory = null;
58        @c public String                        attachmentsUrl = null;
59           @_avoidDisplayingInControlPanel
60        @c public ExternalFile                  attachments = null;
61           @_avoidDisplayingInView
62           @_readOnly
63           public Integer                       commentsCount = writeJS("getThisChange().comments ? comments.COUNT() : commentsCount");
64    }
65  
66    @DavClass._viewCols("title, description, submitter, submitTime, replies, attachments, sizeOfAttachments")
67    @DavClass._largeIcon("icons/classes/Comment-large.gif")
68    @DavClass._smallIcon("icons/classes/Comment-small.gif")
69    @DavClass._gridCols("title, submitTime")
70    @DavClass._icon("icons/classes/Comment.gif")
71    @DavClass._chartViewCols("title")
72    public static interface Note extends Submission, FileSystem, Folder {
73           @_subPropertyOf("rootFolder")
74      @k@c public Annotated                     forum = null;
75           @_displayNameElm
76           @_displaySize(50)
77           @_propertyEditor("FolderResourcePropertyEditor")
78           @_subPropertyOf("subject")
79      @r@s public String                        title = null;
80           @_immutable
81           @_avoidDisplayingOnCreate
82           @_subPropertyOf("parentFolder")
83        @c public Note                          inReplyTo = null;
84           @_icon("icons/status-message-replied.gif")
85           @_backLink("inReplyTo")
86           @_subPropertyOf("folderItems")
87        @c public Note[]                        replies = null;
88           @_readOnly
89           public Integer                       repliesCount = writeJS("getThisChange().replies ? replies.COUNT() : repliesCount");
90           @_displaySize(50)
91           @_displayInline
92        @s public String                        description = null;
93           @_label("Posted by")
94           @_subPropertyOf("submittedBy")
95        @s public Contact                       submitter = null; // = WRITE_JS(submitter == null ? getContact() : submitter);
96           @_label("Posted on")
97           @_subPropertyOf("dateSubmitted")
98        @s public ComplexDate                   submitTime = null; // = WRITE_JS((submitTime == null) ? (getSession() == null ? null : new Date().getTime()) : submitTime); //* when was submitted
99           @_subPropertyOf("attachmentsUrl")
100       @c public String                        url = null;
101          @_backLink("forResource")
102       @c public SharedFile[]                  attachments = null;
103       @c public fileSize                      sizeOfAttachments = null; //* total size of attachments
104       @c public Integer                       attachmentsCount = null; //* total number of attachments
105   }
106 
107   public static class Annotation implements Note {
108     @k@c public Annotated                     forum;
109     @r@c public String                        title;
110       @c public Annotation                    inReplyTo;
111          @_backLink("inReplyTo")
112       @c public Annotation[]                  replies;
113       @c public String                        description;
114          @_label("Posted by")
115       @c public Contact                       submitter; // = WRITE_JS(submitter == null ? getContact() : submitter);
116          @_label("Posted on")
117       @c public ComplexDate                   submitTime; // = WRITE_JS((submitTime == null) ? (getSession() == null ? null : new Date().getTime()) : submitTime); //* when was submitted
118       @c public String                        url;
119          @_backLink("forResource")
120       @c public SharedFile[]                  attachments;
121       @c public fileSize                      sizeOfAttachments; //* total size of attachments
122   }
123 
124   /**
125  *  Any resource of a class that implements CollaborationPoint can become
126  *  a discussion forum. This means that Comment resource could be associated with
127  *  a CollaborationPoint and such Comment resources can be created from
128  *  email or WEB interface.
129  */
130   public static interface CollaborationPoint extends Submission, Annotated {
131          @_avoidModificationTracking
132          @_readOnly
133          @_notSearchable
134          @_backLink("forum")
135          public Subscription[]                members = null;
136          @_avoidModificationTracking
137          @_readOnly
138          @_where("messageAccount = 'self'")
139          @_notSearchable
140          @_backLink("forum")
141          public Subscription[]                mySubscription = null;
142          @_avoidModificationTracking
143          @_readOnly
144          @_notSearchable
145          @_backLink("invitedTo")
146          public Invitation[]                  invited = null;
147          @_avoidModificationTracking
148          @_readOnly
149          @_notSearchable
150          @_backLink("forum")
151          public PendingSubscription[]         pending = null; //* permission to subscribe requests
152          @_readOnly
153          @_maxDisplayInplace(5)
154          @_where("to == 'self' && markedAsRead == false")
155          @_notSearchable
156          @_backLink("forum")
157          public ReminderAlert[]               reminders = null;
158          @_maxDisplayInplace(5)
159          @_icon("icons/alert.gif")
160          @_backLink("associatedWith")
161          @_where("to == 'self' && markedAsRead == false")
162          @_avoidDisplayingInControlPanel
163          @_readOnly
164          @_notSearchable
165          public Message[]                     myUnreadMessages = null;
166          @_maxDisplayInplace(5)
167          @_icon("icons/flag.gif")
168          @_backLink("associatedWith")
169          @_where("to == 'self' && flagForFollowUp == true")
170          @_avoidDisplayingInControlPanel
171          @_readOnly
172          @_notSearchable
173          public Message[]                     myFlaggedMessages = null;
174          @_maxSize(2000)
175          @_readOnly
176          public String                        summary = null;
177          @_maxSize(1000)
178          @_readOnly
179          public String                        contents = null;
180          @_backLink("forum")
181       @c public Comment[]                     comments = null;
182       @c public Comment                       lastComment = null;
183          @_backLink("forResource")
184       @c public ChatHistoryFile[]             chatHistory = null;
185       @c public String                        attachmentsUrl = null;
186       @c public ExternalFile                  attachments = null;
187       @c public Integer                       commentsCount = null;
188   }
189 
190   /**
191  * A single comment made on the CollaborationPoint.
192  */
193   public static class Comment implements Note {
194       @k public Integer                       seq;
195     @k@c public CollaborationPoint            forum;
196          @_displayNameElm
197     @r@c public String                        title;
198       @c public Comment                       inReplyTo;
199          @_backLink("inReplyTo")
200       @c public Comment[]                     replies;
201       @c public Integer                       repliesCount;
202       @c public String                        description;
203          @_label("Posted by")
204       @c public Contact                       submitter;
205          @_label("Posted on")
206       @c public ComplexDate                   submitTime;
207       @c public String                        url;
208          @_backLink("forResource")
209       @c public SharedFile[]                  attachments;
210       @c public fileSize                      sizeOfAttachments; //* total size of attachments
211       @c public Integer                       attachmentsCount; //* total number of attachments
212   }
213 
214   /**
215  * A single comment made on the CollaborationPoint.
216  */
217   @DavClass._label("Comment")
218   @DavClass._largeIcon("icons/classes/Comment-large.gif")
219   @DavClass._viewCols("seq, title, description, submitter, submitTime, replies, attachments, sizeOfAttachments")
220   @DavClass._smallIcon("icons/classes/Comment-small.gif")
221   @DavClass._icon("icons/classes/Comment.gif")
222   public static class ProtectedComment extends hudsonfog.voc.model.portal.Comment implements AccessControl {
223     @k@s public Integer                       seq;
224     @k@s public CollaborationPoint            forum;
225     @r@s public String                        title;
226          @_onCreate
227       @c public AccessLevel                   accessLevel = writeJS("accessLevel ? accessLevel : 'Site owner'"); //* if 'site owner' - will be shown only to internal people.
228   }
229 
230   public static enum Rating {
231     Lowest, Low, Normal, High, Highest;
232   }
233 
234   /**
235  *  Associates Contact with the CollaborationPoint and specifies level
236  *  of interest for forum messages.
237  */
238   @DavClass._avoidIndexing
239   @DavClass._viewCols("messageAccount, forum, submitted, specialNotice")
240   @DavClass._largeIcon("icons/classes/Subscription-large.gif")
241   @DavClass._icon("icons/classes/Subscription.gif")
242   public static class Subscription {
243          @_displayNameElm
244          @_delegatedAccessControl
245       @k public Contact                       messageAccount;
246          @_containerMember
247          @_delegatedAccessControl
248       @k public CollaborationPoint            forum; //* the collaboration point for this subscription
249       @h public emailAddress                  alertsEmail; //* optional, if missing - Contact's primary email will be used
250          public AlertLevel                    alertLevel; //* limit amount of alerts
251          public SubscriberRole                role;
252          @_readOnly
253          @_avoidDisplaying
254          public Boolean                       subscribed;
255          @_readOnly
256          @_avoidDisplaying
257          public Boolean                       invited;
258          @_readOnly
259          public Boolean                       requested;
260          public Boolean                       sendAlertsToMobile; //* is set when user wants alerts to be sent to his/her mobile phone also
261          @_maxSize(2000)
262          @_propertyEditor("SpecialNoticePropertyEditor")
263          public String                        specialNotice;
264          @_maxSize(2000)
265          public String                        comment; //* may include the message to the subscriber, e.g. the reason for invitivation
266          @_dateFormat("~MMM-dd, yyyy HH:mm")
267          @_readOnly
268          @_sortAscending(false)
269          public ComplexDate                   submitted = writeJS("submitted ? submitted : new Date().getTime()"); //* when was submitted
270          public Contact                       submitter = writeJS("submitter == null ? getContact() : submitter");
271   }
272 
273   public static class MySubscription extends hudsonfog.voc.model.portal.Subscription {
274       @k public Integer                       seq;
275          @_displayNameElm
276          @_subPropertyOf("messageAccount")
277     @k@s public Contact                       owner = writeJS("owner == null ? getContact() : owner");
278     @r@s public CollaborationPoint            forum; //* the collaboration point for this subscription
279   }
280 
281   /**
282  *  Invitation to become a subscriber
283  */
284   @DavClass._aView
285   @DavClass._largeIcon("icons/classes/Invited-large.gif")
286   @DavClass._viewCols("comment, inviter, invitedTo, contact, created, acceptInvitation")
287   @DavClass._where("invited == true  && subscribed == false")
288   @DavClass._icon("icons/classes/Invited.gif")
289   @DavClass._filterView
290   public static class Invitation extends hudsonfog.voc.model.portal.MySubscription {
291          @_displayNameElm
292          @_subPropertyOf("owner")
293       @s public Contact                       contact = writeJS("contact"); //*? Contact you are inviting
294          @_subPropertyOf("forum")
295       @s public CollaborationPoint            invitedTo;
296          @_readOnly
297          @_subPropertyOf("submitter")
298       @s public Contact                       inviter;
299       @s public Boolean                       invited = writeJS("true");
300     @h@s public AlertLevel                    alertLevel;
301       @s public String                        comment; //* Please add a short note to the person you are inviting
302          @_subPropertyOf("alertsEmail")
303       @s public emailAddress                  invitationEmail; //* <b>Optional.</b> This email address will be used to send invitation instead of Contact's default email, which is on file.
304          @_subPropertyOf("submitted")
305       @s public ComplexDate                   created;
306          @_notSearchable // once invitation accepted - no turning back :-)
307          @_immutable
308          @_subPropertyOf("requested")
309          @_colorCoding("'False' icons/status-message-read.gif; 'True' icons/checkboxChecked.gif;")
310       @s public Boolean                       acceptInvitation; //* by changing to yes you agree accept the invitation
311     @h@s public Integer                       seq;
312     @h@s public SubscriberRole                role;
313     @h@s public Boolean                       subscribed;
314     @h@s public Boolean                       sendAlertsToMobile;
315     @h@s public String                        specialNotice;
316   }
317 
318   /**
319  *  Pending subscription - not approved yet
320  */
321   @DavClass._aView
322   @DavClass._largeIcon("icons/classes/Pending-large.gif")
323   @DavClass._where("requested == true && subscribed == false")
324   @DavClass._icon("icons/classes/Pending.gif")
325   @DavClass._filterView
326   public static class PendingSubscription extends hudsonfog.voc.model.portal.MySubscription {
327          @_displayNameElm
328          @_subPropertyOf("owner")
329       @s public Contact                       contact;
330       @s public CollaborationPoint            forum;
331       @s public Boolean                       requested = writeJS("true");
332       @s public SubscriberRole                role;
333       @s public emailAddress                  alertsEmail;
334       @s public AlertLevel                    alertLevel;
335       @s public ComplexDate                   submitted;
336     @h@s public Integer                       seq;
337     @h@s public Boolean                       subscribed;
338     @h@s public Boolean                       invited;
339     @h@s public Boolean                       sendAlertsToMobile;
340     @h@s public String                        specialNotice;
341     @h@s public String                        comment;
342     @h@s public Contact                       submitter;
343   }
344 
345   /**
346  *  Subscribed - approved subscription request
347  */
348   @DavClass._aView
349   @DavClass._where("subscribed == true")
350   @DavClass._filterView
351   public static class Subscribed extends hudsonfog.voc.model.portal.MySubscription {
352          @_displayNameElm
353          @_subPropertyOf("owner")
354       @s public Contact                       contact;
355       @s public CollaborationPoint            forum;
356          @_propertyEditor("SpecialNoticePropertyEditor")
357       @s public String                        specialNotice;
358       @s public Boolean                       subscribed = writeJS("true");
359       @s public SubscriberRole                role;
360       @s public AlertLevel                    alertLevel;
361       @s public emailAddress                  alertsEmail;
362       @s public Boolean                       sendAlertsToMobile;
363       @s public ComplexDate                   submitted;
364     @h@s public Integer                       seq;
365     @h@s public Boolean                       invited;
366     @h@s public Boolean                       requested;
367     @h@s public String                        comment;
368     @h@s public Contact                       submitter;
369   }
370 
371   public static enum SubscriberRole {
372     admin, owner, subscriber;
373   }
374 
375   public static enum AlertLevel {
376     All, Conditional;
377   }
378 
379   /**
380  *  Associates Contact with the CollaborationPoint and specifies level
381  *  of interest for forum messages.
382  */
383   @DavClass._avoidIndexing
384   @DavClass._largeIcon("icons/classes/Watch-large.gif")
385   @DavClass._viewCols("messageAccount, forClass, submitted, recipient, specialNotice, comment, cancelled")
386   @DavClass._icon("icons/classes/Watch.gif")
387   public static class Watch implements Cancellable {
388       @k public Integer                       seq;
389          @_displayNameElm
390          @_delegatedAccessControl
391       @k public GenericMessageAccount         messageAccount;
392          @_readOnly
393          @_delegatedAccessControl
394       @r public DavClass                      forClass; //* the collaboration point for this subscription
395          public emailAddress                  alertsEmail; //* optional, if missing - Contact's primary email will be used
396          public Contact                       recipient; //* person that will receive alerts for this watch (if not specified - owner of the watch)
397          @_readOnly
398          @_avoidDisplaying
399          public AlertLevel                    alertLevel; //* allows to specify the alerts you desire to receive
400          @_readOnly
401          @_allowRoles("admin")
402          public SubscriberRole                role;
403          @_readOnly
404          @_avoidDisplaying
405          public Boolean                       subscribed;
406          @_readOnly
407          @_avoidDisplaying
408          public Boolean                       invited;
409          @_readOnly
410          public Boolean                       requested;
411          @_maxSize(2000)
412          @_propertyEditor("SpecialNoticePropertyEditor")
413          public String                        specialNotice;
414          @_maxSize(1000)
415          public String                        comment; //* add a note that describes this watch
416          @_dateFormat("~MMM-dd, yyyy HH:mm")
417          @_readOnly
418          @_sortAscending(false)
419          public ComplexDate                   submitted = writeJS("submitted ? submitted : new Date().getTime()"); //* when was submitted
420       @c public Boolean                       cancelled;
421   }
422 
423   public static class MyWatch extends hudsonfog.voc.model.portal.Watch {
424     @k@s public Integer                       seq;
425          @_subPropertyOf("messageAccount")
426     @k@s public Contact                       owner = writeJS("owner == null ? getContact() : owner");
427     @r@s public DavClass                      forClass; //* the collaboration point for this subscription
428          @_readOnly
429          @_avoidDisplaying
430          public ExternalOrganization          organization = formula("owner.organization");
431   }
432 
433   @DavClass._viewCols("title, description, forum, meetingDuration, meetingFrequency, openedBy, dateOpened, touched, myUnreadMessages, myFlaggedMessages, attachments, sizeOfAttachments")
434   @DavClass._largeIcon("icons/classes/Meeting-large.gif")
435   @DavClass._icon("icons/classes/Meeting.gif")
436   public static class Meeting implements RecurrentItem, CollaborationPoint, FileSystem, ModificationHistory, Cancellable {
437       @k public CollaborationPoint            forum;
438       @k public Integer                       seq;
439          @_displayNameElm
440          @_cloneOf("subject")
441     @r@c public String                        title; // brief description of this meeting
442       @c public String                        description; // more detailed description
443          @_abstract
444          @_cloneOf("start")
445       @c public ComplexDate                   meetingTime; //* at what date/time event should start
446          @_abstract
447          @_cloneOf("end")
448       @c public ComplexDate                   meetingEndTime; //* at what date/time event should end
449          @_cloneOf("frequency")
450       @c public Frequency                     meetingFrequency; //* defines the recurrent pattern
451       @c public dateTime                      repeatFrom; //* marks that this event should not start repeating until this date
452       @c public dateTime                      repeatUntil; //* marks that this event should not stop repeating after this date
453     @h@c public Integer                       maxRepetitions; //* marks that this event should stop repeating after this many iterations
454          @_cloneOf("duration")
455       @c public Duration                      meetingDuration; //* duration of the event
456          @_abstract
457       @c public ComplexDate                   eventTime;
458          @_backLink("forum")
459       @c public Comment[]                     comments;
460          @_cloneOf("submittedBy")
461       @c public Contact                       openedBy; // = WRITE_JS(openedBy == null ? getContact() : openedBy);
462          @_sortAscending
463          @_cloneOf("dateSubmitted")
464       @c public ComplexDate                   dateOpened; //* when this message entered the system
465          @_backLink("forum")
466          public Bookmark[]                    bookmarks;
467          @_backLink("meeting")
468          @_extractSubscribers
469          public MeetingParticipant[]          meetingParticipants;
470          @_backLink("forum")
471          @_cloneOf("members")
472       @c public Subscribed[]                  subscribers;
473          @_backLink("invitedTo")
474          @_cloneOf("invited")
475       @c public Invitation[]                  invitedSubscribers;
476          @_backLink("forum")
477          @_cloneOf("pending")
478       @c public PendingSubscription[]         pendingSubscribers; //* permission to subscribe requests
479       @c public Modification                  lastModification;
480          @_dateFormat("~MMM-dd, yyyy HH:mm")
481          @_readOnly
482       @c public dateTime                      lastModified; //* when meeting was last modified
483       @c public dateTime                      touched;
484          @_backLink("forResource")
485          @_displayInline
486       @c public Modification[]                changeHistory; //* list of modifications for this resource
487       @c public Comment                       lastComment;
488          @_dateFormat("~MMM-dd, yyyy HH:mm")
489          @_readOnly
490          @_icon("icons/classes/Comment.gif")
491          @_notSearchable // property name is too long for Filter panel, besides - it is not very useful to search by
492          public ComplexDate                   lastCommentTime = formula("lastComment.submitTime");
493          @_backLink("meeting")
494       @c public MeetingAlert[]                reminders;
495          @_backLink("associatedWith")
496       @c public Message[]                     myUnreadMessages;
497          @_backLink("associatedWith")
498       @c public Message[]                     myFlaggedMessages;
499          @_cloneOf("attachmentsUrl")
500       @c public String                        url;
501          @_backLink("forResource")
502       @c public ExternalFile[]                attachments;
503       @c public fileSize                      sizeOfAttachments; //* total size of attachments
504       @c public Boolean                       cancelled;
505   }
506 
507   @DavClass._viewCols("contact, meeting, role, notes")
508   public static class MeetingParticipant {
509          @_displayNameElm
510       @k public Contact                       contact;
511       @k public Meeting                       meeting;
512          @_onCreate
513          public MeetingRole                   role = writeJS("role ? role : 'Participant'"); //* role of this participant in a meeting
514          @_maxSize(1000)
515          public String                        notes;
516   }
517 
518   @DavClass._aView
519   @DavClass._filterView
520   public static class MyMeeting extends hudsonfog.voc.model.portal.Meeting {
521          public Contact                       contact = formula("meetingParticipants.contact");
522       @s public CollaborationPoint            forum;
523          @_displayNameElm
524       @s public String                        title;
525       @s public String                        description;
526          @_abstract
527       @s public ComplexDate                   meetingTime;
528          @_abstract
529       @s public ComplexDate                   meetingEndTime;
530       @s public Frequency                     meetingFrequency;
531       @s public dateTime                      repeatFrom;
532       @s public dateTime                      repeatUntil;
533     @h@s public Integer                       maxRepetitions;
534       @s public Duration                      meetingDuration;
535       @s public Contact                       openedBy;
536       @s public ComplexDate                   dateOpened;
537          @_backLink("meeting")
538       @s public MeetingParticipant[]          meetingParticipants;
539          @_backLink("forum")
540       @s public Subscribed[]                  subscribers;
541          @_backLink("invitedTo")
542       @s public Invitation[]                  invitedSubscribers;
543          @_backLink("forum")
544       @s public PendingSubscription[]         pendingSubscribers;
545       @s public Modification                  lastModification;
546       @s public dateTime                      lastModified;
547       @s public dateTime                      touched;
548          @_backLink("forResource")
549          @_displayInline
550       @s public Modification[]                changeHistory;
551       @s public Comment                       lastComment;
552       @s public ComplexDate                   lastCommentTime;
553          @_backLink("meeting")
554       @s public MeetingAlert[]                reminders;
555          @_backLink("associatedWith")
556       @s public Message[]                     myUnreadMessages;
557          @_backLink("associatedWith")
558       @s public Message[]                     myFlaggedMessages;
559       @s public String                        url;
560          @_backLink("forResource")
561       @s public ExternalFile[]                attachments;
562       @s public fileSize                      sizeOfAttachments;
563     @h@s public Integer                       seq;
564     @h@s public ComplexDate                   eventTime;
565          @_backLink("forum")
566     @h@s public Comment[]                     comments;
567          @_backLink("forum")
568     @h@s public Bookmark[]                    bookmarks;
569     @h@s public Boolean                       cancelled;
570   }
571 
572   public static enum MeetingRole {
573     Organizer, Assistant, Participant;
574   }
575 
576   @DavClass._largeIcon("icons/classes/Forum-large.gif")
577   @DavClass._viewCols("title, description, openedBy, dateOpened, comments, lastCommentTime, myUnreadMessages, myFlaggedMessages, attachments, sizeOfAttachments")
578   @DavClass._gridCols("title")
579   @DavClass._icon("icons/classes/Forum.gif")
580   public static class Forum implements CollaborationPoint, FileSystem, Taggable, ModificationHistory {
581          @_autoincrement
582          @_readOnly
583       @k public Integer                       id;
584          public CollaborationPoint            associatedWith;
585          @_resourceLink
586          @_displayNameElm
587          @_cloneOf("subject")
588     @r@c public String                        title; //* brief description of this forum
589          @_maxSize(60000)
590          @_propertyEditor("HtmlPropertyEditor")
591          @_displayInline
592       @c public longString                    description; //* more detailed description
593          @_backLink("forum")
594          @_displayInline
595       @c public Comment[]                     comments;
596       @c public Integer                       commentsCount;
597       @c public Comment                       lastComment;
598          @_cloneOf("submittedBy")
599       @c public Contact                       openedBy; // = WRITE_JS(openedBy == null ? getContact() : openedBy);
600          @_backLink("forum")
601          @_cloneOf("members")
602       @c public Subscribed[]                  subscribers;
603          @_backLink("invitedTo")
604          @_cloneOf("invited")
605       @c public Invitation[]                  invitedSubscribers;
606          @_backLink("forum")
607          @_cloneOf("pending")
608       @c public PendingSubscription[]         pendingSubscribers; //* permission to subscribe requests
609          @_cloneOf("dateSubmitted")
610       @c public ComplexDate                   dateOpened; //* when this message entered the system
611          @_dateFormat("~MMM-dd, yyyy HH:mm")
612          @_readOnly
613          @_icon("icons/classes/Comment.gif")
614          public ComplexDate                   lastCommentTime = formula("lastComment.submitTime");
615          @_backLink("associatedWith")
616       @c public Message[]                     myUnreadMessages;
617          @_backLink("associatedWith")
618       @c public Message[]                     myFlaggedMessages;
619          @_cloneOf("attachmentsUrl")
620       @c public String                        url;
621          @_backLink("forResource")
622       @c public ExternalFile[]                attachments;
623       @c public fileSize                      sizeOfAttachments; //* total size of attachments
624       @c public Integer                       attachmentsCount; //* total number of attachments
625          @_avoidDisplayingInView
626       @c public String                        summary;
627          @_avoidDisplayingInView
628       @c public String                        contents;
629       @c public tags                          tags;
630          @_backLink("taggable")
631       @c public TagUse[]                      tagUse;
632       @c public Modification                  lastModification;
633          @_dateFormat("~MMM-dd, yyyy HH:mm")
634          @_readOnly
635       @c public dateTime                      lastModified;
636       @c public dateTime                      touched;
637          @_backLink("forResource")
638       @c public Modification[]                changeHistory; //* list of modifications for this resource
639   }
640 
641   /**
642  * An Event scheduled for some specific date and time. May be repeating.
643  */
644   @DavClass._viewCols("title, description, forum, duration, frequency, tags, myUnreadMessages, myFlaggedMessages, attachments")
645   @DavClass._largeIcon("icons/calendar-day-large.gif")
646   @DavClass._icon("icons/calendar-day.gif")
647   public static class Event implements CollaborationPoint, FileSystem, ModificationHistory, RecurrentItem, Taggable, FolderItem, Cancellable {
648          @_displayNameElm
649          @_cloneOf("subject")
650     @r@c public String                        title;
651          @_autoincrement
652          @_readOnly
653       @k public Integer                       id;
654          @_notifyContainer
655          @_cloneOf("folder")
656       @c public CollaborationPoint            forum;
657       @c public String                        description;
658          @_abstract
659       @c public ComplexDate                   start; //* at what date/time event should start
660          @_abstract
661       @c public ComplexDate                   end; //* at what date/time event should end
662          @_sortAscending
663       @c public Frequency                     frequency; //* defines the recurrent pattern
664       @c public dateTime                      repeatFrom; //* marks that this event should not start repeating until this date
665       @c public dateTime                      repeatUntil; //* marks that this event should not stop repeating after this date
666     @h@c public Integer                       maxRepetitions; //* marks that this event should stop repeating after this many iterations
667       @c public Duration                      duration; //* duration of the event
668          @_abstract
669       @c public ComplexDate                   eventTime;
670          @_backLink("forum")
671       @c public Comment[]                     comments;
672          @_cloneOf("submittedBy")
673       @c public Contact                       openedBy;
674          @_sortAscending
675          @_cloneOf("dateSubmitted")
676       @c public ComplexDate                   dateOpened; //* when this message entered the system
677          @_backLink("forum")
678          @_cloneOf("members")
679       @c public Subscribed[]                  subscribers;
680          @_backLink("invitedTo")
681          @_cloneOf("invited")
682       @c public Invitation[]                  invitedSubscribers;
683       @c public Modification                  lastModification;
684          @_dateFormat("~MMM-dd, yyyy HH:mm")
685          @_readOnly
686       @c public dateTime                      lastModified;
687       @c public dateTime                      touched;
688          @_backLink("forResource")
689          @_displayInline
690       @c public Modification[]                changeHistory; //* list of modifications for this resource
691       @c public Comment                       lastComment;
692          @_dateFormat("~MMM-dd, yyyy HH:mm")
693          @_icon("icons/classes/Comment.gif")
694          @_readOnly
695          @_notSearchable // property name is too long for Filter panel, besides - it is not very useful to search by
696          public ComplexDate                   lastCommentTime = formula("lastComment.submitTime");
697          @_backLink("forum")
698       @c public ReminderAlert[]               reminders;
699          @_backLink("associatedWith")
700       @c public Message[]                     myUnreadMessages;
701          @_backLink("associatedWith")
702       @c public Message[]                     myFlaggedMessages;
703          @_cloneOf("attachmentsUrl")
704       @c public String                        url;
705          @_backLink("forResource")
706       @c public ExternalFile[]                attachments;
707       @c public fileSize                      sizeOfAttachments; //* total size of attachments
708       @c public tags                          tags;
709          @_backLink("taggable")
710       @c public TagUse[]                      tagUse;
711       @c public Boolean                       cancelled;
712   }
713 
714   /**
715  * A Travel event.
716  */
717   @DavClass._largeIcon("icons/classes/Travel-large.gif")
718   @DavClass._viewCols("title, description, forum, duration, frequency, departureFrom, arrivalTo, tags, myUnreadMessages, myFlaggedMessages, attachments")
719   @DavClass._icon("icons/classes/Travel.gif")
720   public static class Travel extends hudsonfog.voc.model.portal.Event {
721          @_displayNameElm
722     @r@s public String                        title;
723     @k@s public Integer                       id;
724          public String                        departureFrom; //* departure airport, railway/bus station, etc.
725          public String                        arrivalTo; //* arrival airport, railway/bus station, etc.
726          public String                        reservationNumber;
727          public String                        confirmationNumber;
728   }
729 
730   /**
731  * A Hotel event.
732  */
733   @DavClass._viewCols("title, description, forum, frequency, duration, hotelName, tags, myUnreadMessages, myFlaggedMessages, attachments")
734   @DavClass._largeIcon("icons/classes/Hotel-large.gif")
735   @DavClass._icon("icons/classes/Hotel.gif")
736   public static class Hotel extends hudsonfog.voc.model.portal.Event implements Address {
737          @_displayNameElm
738     @r@s public String                        title;
739     @k@s public Integer                       id;
740          public String                        hotelName;
741          public String                        reservationNumber;
742          public String                        roomType;
743          @_propertyGroupList("city, region, postalCode, address1, country")
744          @_abstract
745          @_propertyGroup("true")
746          public Boolean                       address;
747       @c public Country                       country;
748       @c public String                        region; //* state, province, territory or other country subdivision
749       @c public String                        city; //* city, town, village, township
750       @c public String                        postalCode; //* Zip code or Postal code
751       @c public String                        address1; //* street address, building number, PO Box, etc.
752       @c public String                        address2; //* second part of address string
753   }
754 
755   /**
756  * News item. Can be emailed or entered online.
757  */
758   @DavClass._largeIcon("icons/classes/News-large.gif")
759   @DavClass._icon("icons/classes/News.gif")
760   public static class News extends hudsonfog.voc.model.portal.Forum {
761     @k@s public Integer                       id;
762     @r@s public CollaborationPoint            associatedWith;
763          @_displayNameElm
764     @r@s public String                        title; //* news item's title
765          @_subPropertyOf("dateOpened")
766       @s public ComplexDate                   datePosted; //* date this news item was posted
767   }
768 
769   @DavClass._largeIcon("icons/classes/Group-large.gif")
770   @DavClass._viewCols("title, description, openedBy, dateOpened, myUnreadMessages, myFlaggedMessages, attachments, sizeOfAttachments")
771   @DavClass._icon("icons/classes/Group.gif")
772   public static class Group implements CollaborationPoint, FileSystem, ModificationHistory {
773          @_cloneOf("dateSubmitted")
774     @k@c public ComplexDate                   dateOpened; //* when this message entered the system
775          @_displayNameElm
776          @_cloneOf("subject")
777     @k@c public String                        title; //* brief description of this group
778       @c public String                        description; //* more detailed description
779          @_backLink("forResource")
780       @c public SharedFile[]                  attachments;
781          @_cloneOf("attachmentsUrl")
782       @c public String                        url;
783       @c public fileSize                      sizeOfAttachments; //* total size of attachments
784          @_cloneOf("submittedBy")
785       @c public Contact                       openedBy;
786          @_backLink("associatedWith")
787          public News[]                        news;
788          @_backLink("forum")
789          public Bookmark[]                    bookmarks;
790          @_backLink("associatedWith")
791          @_displayInline
792          public Forum[]                       forums;
793          @_backLink("forum")
794       @c public Comment[]                     comments;
795       @c public Comment                       lastComment;
796          @_backLink("forum")
797          @_cloneOf("members")
798       @c public Subscribed[]                  subscribers;
799          @_backLink("invitedTo")
800          @_cloneOf("invited")
801       @c public Invitation[]                  invitedSubscribers;
802          @_backLink("forum")
803          @_cloneOf("pending")
804       @c public PendingSubscription[]         pendingSubscribers; //* permission to subscribe requests
805          @_backLink("associatedWith")
806       @c public Message[]                     myUnreadMessages;
807          @_backLink("associatedWith")
808       @c public Message[]                     myFlaggedMessages;
809       @c public Integer                       commentsCount;
810       @c public dateTime                      touched;
811          @_backLink("forResource")
812       @c public Modification[]                changeHistory; //* list of modifications for this resource
813       @c public Modification                  lastModification;
814          @_dateFormat("~MMM-dd, yyyy HH:mm")
815          @_icon("icons/edit.gif")
816          @_readOnly
817       @c public dateTime                      lastModified;
818       @c public String                        editNotes; //*? important: notes explaining your changes
819   }
820 
821   @DavClass._viewCols("title, dateCreated, notes")
822   @DavClass._largeIcon("icons/classes/Bookmark-large.gif")
823   @DavClass._icon("icons/classes/Bookmark.gif")
824   public static class BookmarkItem implements FolderItem, Taggable {
825          @_autoincrement
826          @_alwaysReturnToClient // need to generate dashboards
827          @_avoidDisplaying
828       @k public Integer                       id;
829          @_alwaysReturnToClient // need to generate dashboards
830       @r public Contact                       creator = writeJS("creator == null ? getContact() : creator"); //* creator of the bookmark
831          @_displayNameElm
832       @r public String                        title;
833          @_maxSize(1000)
834          public String                        notes; //* more detailed description
835          public CollaborationPoint            forum; //* optional - you can add bookmark to a Group, Workplace, etc.
836       @c public BookmarkFolder                folder; //* optional bookmark folder
837          @_icon("icons/dateReceived.gif")
838          @_sortAscending(false)
839          @_onCreate
840          @_dateFormat("~MMM-dd, yyyy HH:mm")
841          @_readOnly
842          public ComplexDate                   dateCreated = writeJS("dateCreated ? dateCreated : new Date().getTime()");
843       @c public tags                          tags;
844          @_backLink("taggable")
845       @c public TagUse[]                      tagUse;
846   }
847 
848   /**
849  * Bookmark folder.
850  */
851   public static class BookmarkFolder extends hudsonfog.voc.model.portal.BookmarkItem implements Folder {
852     @k@s public Integer                       id;
853          @_displayNameElm
854     @r@s public String                        title; //* choose a name that will remind you later what this folder represents
855          @_subPropertyOf("folder")
856       @s public BookmarkFolder                parentFolder;
857          @_backLink("folder")
858          @_cloneOf("folderItems")
859       @c public Bookmark[]                    bookmarks;
860   }
861 
862   /**
863  * Bookmark is a saved address of some page.
864  */
865   @DavClass._avoidIndexing
866   @DavClass._largeIcon("icons/classes/Bookmark-large.gif")
867   @DavClass._viewCols("title, dateCreated, notes, bookmarks, dashboardColumn, previousInColumn")
868   @DavClass._icon("icons/classes/Bookmark.gif")
869   @DavClass._skipAccessControl
870   public static class Bookmark extends hudsonfog.voc.model.portal.BookmarkItem implements FolderItem, Styled {
871     @k@s public Integer                       id;
872          @_clientScript("onFocus: document.location.href.indexOf('mkResource.html') == -1 ? this.value : this.value ? this.value : this.value=document.title") // this.value is the value of current form field - .title
873          @_uiFocus
874          @_displayNameElm
875          @_setLinkTo("pageUrl")
876     @r@s public String                        title; //* choose a name that will remind you later what this page represents
877          @_maxSize(9000)
878          @_alwaysReturnToClient
879          public href                          pageUrl;
880          @_alwaysReturnToClient
881          @_avoidDisplaying
882          public DavClass                      forClass;
883          @_maxSize(3000)
884          @_alwaysReturnToClient
885          @_oldName("code")
886          @_propertyEditor("LiteralPropertyEditor")
887          public String                        embeddedCode; //* code of the embedded third-party widget
888          @_readOnly
889          @_avoidDisplaying
890          public Boolean                       isList = writeJS("getThisChange().pageUrl ? Packages.com.fog.webdav.WebDavUtils.isList(pageUrl) : null");
891          @_containerMember
892          @_where("pageUrl == null  &&  embeddedCode == null  &&  dashboard != null")
893          public Bookmark                      parent; // parent boomark, like pure dashboard or bookmark with neighbourhood (sidebars)
894          @_displayNameElm
895          @_containerMember
896          @_immutable
897          public Dashboard                     dashboard = writeJS("getThisChange().dashboard ? dashboard : getThisChange().parent ? parent.dashboard : dashboard");
898          @_alwaysReturnToClient
899          @_avoidDisplaying
900          public DavClass                      parentForClass = formula("parent.forClass");
901          @_readOnly
902          @_alwaysReturnToClient
903          @_avoidDisplaying
904          public DavProperty                   backlink; // backlink property this widget corresponds to
905          @_backLink("parent")
906          @_displayInline
907          public Bookmark[]                    bookmarks;
908          @_readOnly
909          public Integer                       bookmarksCount = writeJS("getThisChange().bookmarks ? bookmarks.COUNT() : bookmarksCount");
910          @_alwaysReturnToClient
911          public href                          icon;
912          @_alwaysReturnToClient
913          public href                          largeIcon;
914          @_maxSize(1000)
915          @_readOnly
916          @_notSearchable
917          @_alwaysReturnToClient
918          public list                          closeForProperties; // backlink properties for which bookmarks were explicitely closed
919          @_maxSize(1000)
920          @_readOnly
921          @_alwaysReturnToClient
922          @_notSearchable
923          @_avoidDisplaying
924          public list                          minimizeForProperties; // = WRITE_JS(getMinimizedBookmark()); // backlink properties for which bookmarks were explicitely minimized
925          @_alwaysReturnToClient
926          public Integer                       dashboardColumn;
927          @_alwaysReturnToClient
928          public Bookmark                      previousInColumn;
929          public Sidebar                       sidebar; //* top, bottom, left, right - default center
930          @_alwaysReturnToClient
931          public String                        skin; //* skin for widget
932          @_alwaysReturnToClient
933          public Duration                      refresh; //* how often widget needs to be refreshed
934          @_label("limit")
935          @_alwaysReturnToClient
936          public Integer                       numberOfResources; //* how many resources to show (default = 5)
937          @_alwaysReturnToClient
938          public Integer                       numberInRow; //* how many resources in row to show (default = 1)
939          public String                        defaultcon; //* shows while widget is loading (needed for Apple widgets)
940          public Boolean                       minitab; //* is 'Yes' - display Tab as simple link
941          public Boolean                       showAsTab; //* is 'Yes' - regular Bookmark will show as Tab
942          @_alwaysReturnToClient
943          public Boolean                       removeFrame; //* is 'Yes' - regular box frame is not painted when displayed as widget
944          @_alwaysReturnToClient
945          public Boolean                       removeTitleBackground; //* is 'Yes' - title of widget is displayed without background
946          @_cloneOf("styleSheet")
947       @c public styleSheet                    titleStyleSheet;
948          public Boolean                       isHistory;
949   }
950 
951   @DavClass._skipAccessControl
952   public static class Dashboard extends hudsonfog.voc.model.portal.BookmarkItem {
953     @k@s public Integer                       id;
954          @_displayNameElm
955          @_uiFocus
956          @_setLinkTo("pageUrl")
957     @r@s public String                        title; //* choose a name that will remind you later what this page represents
958          @_maxSize(9000)
959          public href                          pageUrl;
960          @_where("pageUrl == null  &&  embeddedCode == null  &&  parent == null")
961          @_backLink("dashboard")
962          public Bookmark[]                    tabs;
963          public Boolean                       defaultDashboard;
964   }
965 
966   public static enum Sidebar {
967     left, right, top, bottom, center;
968   }
969 
970   @DavClass._viewCols("name, description, owner, lastModified, lastCommentTime, touched, myUnreadMessages, myFlaggedMessages, size")
971   public static class SharedFile extends hudsonfog.voc.system.parse.ExternalFile implements FileSystem, CollaborationPoint, ModificationHistory, Taggable {
972     @k@s public String                        url;
973          @_icon("icons/description.gif")
974       @c public String                        description;
975          @_avoidDisplaying
976          @_backLink("forum")
977          @_cloneOf("members")
978       @c public Subscription[]                subscription;
979          @_backLink("forum")
980          public Subscribed[]                  subscribers;
981          @_backLink("invitedTo")
982          @_cloneOf("invited")
983       @c public Invitation[]                  invitedSubscribers;
984          @_backLink("forum")
985          @_cloneOf("pending")
986       @c public PendingSubscription[]         pendingSubscribers; //* permission to subscribe requests
987          @_backLink("forum")
988          @_displayInline
989       @c public Comment[]                     comments;
990       @c public Integer                       commentsCount;
991       @c public Comment                       lastComment;
992          @_dateFormat("~MMM-dd, yyyy HH:mm")
993          @_readOnly
994          @_icon("icons/classes/Comment.gif")
995          public ComplexDate                   lastCommentTime = formula("lastComment.submitTime");
996          @_backLink("associatedWith")
997       @c public Message[]                     myUnreadMessages;
998          @_backLink("associatedWith")
999       @c public Message[]                     myFlaggedMessages;
1000      @c public Modification                  lastModification;
1001      @s public dateTime                      lastModified; // HACK will be removed after .hf becomes JAVA
1002         @_cloneOf("lastModified")
1003      @c public dateTime                      modified;
1004         @_sortAscending(false)
1005      @c public dateTime                      touched = writeJS("lastModified");
1006         @_backLink("forResource")
1007         @_displayInline
1008      @c public Modification[]                changeHistory; //* list of modifications for this resource
1009      @c public String                        editNotes; //*? important: notes explaining your changes
1010      @c public tags                          tags; //* keywords describing this picture
1011         @_backLink("taggable")
1012      @c public TagUse[]                      tagUse;
1013    @h@s public User                          user;
1014         @_cloneOf("attachmentsUrl")
1015      @c public String                        fileSystem;
1016         @_backLink("forResource")
1017      @c public SharedFile[]                  attachments;
1018  }
1019
1020  /*
1021class MimeType {
1022  string(100)  mimeType;
1023  string(1000) fileExtensions;
1024}
1025*/
1026  @DavClass._gridCols("text")
1027  public static class ImageAnnotation {
1028         @_autoincrement
1029      @k public Integer                       id;
1030         @_containerMember
1031      @r public Image                         notedImage;
1032         public String                        text;
1033         public Integer                       left;
1034         public Integer                       top;
1035         public Integer                       width;
1036         public Integer                       height;
1037  }
1038
1039  @DavClass._viewCols("name")
1040  @DavClass._hideControlPanelInView
1041  public static class Html extends hudsonfog.voc.model.portal.SharedFile {
1042         @_resourceLink(false)
1043         @_propertyEditor("HtmlPropertyEditor")
1044         @_displayInline
1045    @k@s public String                        url;
1046         @_avoidDisplaying
1047      @s public fileSize                      size;
1048         @_avoidDisplaying
1049      @s public String                        mimeType = writeJS("mimeType ? mimeType : 'text/html'");
1050         @_avoidDisplaying
1051      @s public String                        description;
1052         @_backLink("forResource")
1053         @_allowRoles("admin")
1054      @s public Modification[]                changeHistory;
1055         @_avoidDisplaying
1056      @s public dateTime                      touched;
1057         @_avoidDisplaying
1058      @s public String                        editNotes;
1059         @_avoidDisplayingInView
1060         @_alwaysReturnToClient
1061      @s public Integer                       commentsCount;
1062         @_avoidDisplayingInView
1063         @_alwaysReturnToClient
1064         @_subPropertyOf("owner")
1065      @s public Contact                       postedBy;
1066  }
1067
1068  @DavClass._largeIcon("icons/classes/Image-large.gif")
1069  @DavClass._viewCols("name")
1070  @DavClass._defaultImage("images/defaultImage.jpg")
1071  @DavClass._icon("icons/classes/Image.gif")
1072