001    /*
002     * 
003     * $Revision: 14841 $ $Date: 2009-03-09 17:39:27 +0100 (Mon, 09 Mar 2009) $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    package org.mycore.user;
025    
026    import static org.mycore.common.MCRConstants.XLINK_NAMESPACE;
027    import static org.mycore.common.MCRConstants.XSI_NAMESPACE;
028    
029    import java.sql.Timestamp;
030    import java.util.ArrayList;
031    import java.util.GregorianCalendar;
032    import java.util.List;
033    
034    import org.jdom.Element;
035    import org.mycore.common.MCRException;
036    
037    /**
038     * Instances of this class represent MyCoRe groups.
039     * <p>
040     * The main duty of a group object is to define exactly which members it will
041     * have.
042     * 
043     * @see org.mycore.user.MCRUserMgr
044     * @see org.mycore.user.MCRUserObject
045     * 
046     * @author Detlev Degenhardt
047     * @author Jens Kupferschmidt
048     * @author Heiko Helmbrecht
049     * @version $Revision: 14841 $ $Date: 2007-05-02 22:23:40 +0200 (Mi, 02 Mai
050     *          2007) $
051     */
052    public class MCRGroup extends MCRUserObject implements MCRPrincipal {
053            /** A list of users which have the privilege to administer this group */
054            private ArrayList<String> admUserIDs = null;
055    
056            /**
057             * A list of groups which members have the privilege to administer this
058             * group
059             */
060            private ArrayList<String> admGroupIDs = null;
061    
062            /** A list of users (IDs) which are members of this group */
063            private ArrayList<String> mbrUserIDs = null;
064    
065            /**
066             * Default constructor. It is used to create a group object with empty
067             * fields. This is useful for constructing an XML representation of a group
068             * without specialized data. This empty group object will not be created in
069             * the persistent data store.
070             */
071            public MCRGroup() {
072                    super();
073                    admUserIDs = new ArrayList<String>();
074                    admGroupIDs = new ArrayList<String>();
075                    mbrUserIDs = new ArrayList<String>();
076            }
077    
078            /* copy constructor */
079            public MCRGroup(MCRGroup other) {
080                    super();
081                    this.admUserIDs = new ArrayList<String>(other.admUserIDs);
082                    this.admGroupIDs = new ArrayList<String>(other.admGroupIDs);
083                    this.mbrUserIDs = new ArrayList<String>(other.mbrUserIDs);
084                    this.ID = other.ID;
085                    this.creator = other.creator;
086                    this.creationDate = other.creationDate;
087                    this.modifiedDate = other.modifiedDate;
088                    this.description = other.description;
089            }
090    
091            /**
092             * This minimal constructor only takes the group ID as a parameter. For all
093             * other attributes the default constructor is invoked.
094             */
095            public MCRGroup(String id) {
096                    // This constructor is used by the access control system
097                this();
098                    super.ID = id.trim();
099            }
100    
101            /**
102             * This constructor takes a subset of attributes of this class as single
103             * variables and calls the main constructor (taking all attributes) with
104             * default values for the remaining attribute (parameter 'create').
105             * 
106             * @param ID
107             *            the group ID
108             * @param creator
109             *            the user ID who created this group
110             * @param creationDate
111             *            timestamp of the creation of this group, if null the current
112             *            date will be used
113             * @param modifiedDate
114             *            timestamp of the last modification of this group
115             * @param description
116             *            description of the group
117             * @param admUserIDs
118             *            ArrayList of user IDs which have administrative rights for the
119             *            group
120             * @param admGroupIDs
121             *            ArrayList of groups which members have administrative rights
122             *            for the group
123             * @param mbrUserIDs
124             *            ArrayList of user IDs this group has as members
125             */
126            public MCRGroup(String ID, String creator, Timestamp creationDate,
127                            Timestamp modifiedDate, String description,
128                            ArrayList<String> admUserIDs, ArrayList<String> admGroupIDs,
129                            ArrayList<String> mbrUserIDs) throws MCRException, Exception {
130                    super.ID = trim(ID, id_len);
131                    super.creator = trim(creator, id_len);
132    
133                    // check if the creation timestamp is provided. If not, use current
134                    // timestamp
135                    if (creationDate == null) {
136                            super.creationDate = new Timestamp(new GregorianCalendar()
137                                            .getTime().getTime());
138                    } else {
139                            super.creationDate = creationDate;
140                    }
141    
142                    if (modifiedDate == null) {
143                            super.modifiedDate = new Timestamp(new GregorianCalendar()
144                                            .getTime().getTime());
145                    } else {
146                            super.modifiedDate = modifiedDate;
147                    }
148    
149                    this.description = trim(description, description_len);
150                    this.admUserIDs = new ArrayList<String>();
151    
152                    if (admUserIDs != null) {
153                            this.admUserIDs = admUserIDs;
154                    }
155    
156                    this.admGroupIDs = new ArrayList<String>();
157    
158                    if (admGroupIDs != null) {
159                            this.admGroupIDs = admGroupIDs;
160                    }
161    
162                    this.mbrUserIDs = new ArrayList<String>();
163    
164                    if (mbrUserIDs != null) {
165                            this.mbrUserIDs = mbrUserIDs;
166                    }
167            }
168    
169            /**
170             * This constructor creates the data of this object from a given JDOM
171             * Element.
172             * 
173             * @param elm
174             *            the JDOM Element
175             */
176            public MCRGroup(Element elm) {
177                    this();
178    
179                    if (!elm.getName().equals("group")) {
180                            return;
181                    }
182    
183                    super.ID = trim(elm.getAttributeValue("ID"), id_len);
184                    this.creator = trim(elm.getChildTextTrim("group.creator"), id_len);
185    
186                    String tmp = elm.getChildTextTrim("group.creation_date");
187    
188                    if (tmp != null) {
189                            try {
190                                    super.creationDate = Timestamp.valueOf(tmp);
191                            } catch (Exception e) {
192                            }
193                    }
194    
195                    tmp = elm.getChildTextTrim("group.last_modified");
196    
197                    if (tmp != null) {
198                            try {
199                                    super.modifiedDate = Timestamp.valueOf(tmp);
200                            } catch (Exception e) {
201                            }
202                    }
203    
204                    this.description = trim(elm.getChildTextTrim("group.description"),
205                                    description_len);
206    
207                    Element adminElement = elm.getChild("group.admins");
208    
209                    if (adminElement != null) {
210                            List<Element> adminIDList = adminElement.getChildren();
211    
212                            for (int j = 0; j < adminIDList.size(); j++) {
213                                    Element newID = (Element) adminIDList.get(j);
214                                    String id = trim(newID.getTextTrim(), id_len);
215    
216                                    if (newID.getName().equals("admins.userID")) {
217                                            if (!id.equals("")) {
218                                                    addAdminUserID(id);
219                                            }
220    
221                                            continue;
222                                    }
223    
224                                    if (newID.getName().equals("admins.groupID")) {
225                                            if (!id.equals("")) {
226                                                    addAdminGroupID(id);
227                                            }
228                                    }
229                            }
230                    }
231    
232                    Element memberElement = elm.getChild("group.members");
233    
234                    if (memberElement != null) {
235                            List<Element> memberIDList = memberElement.getChildren();
236    
237                            for (int j = 0; j < memberIDList.size(); j++) {
238                                    Element newID = (Element) memberIDList.get(j);
239                                    String id = trim(newID.getTextTrim(), id_len);
240    
241                                    if (newID.getName().equals("members.userID")) {
242                                            if (!id.equals("")) {
243                                                    addMemberUserID(id);
244                                            }
245    
246                                            continue;
247                                    }
248                            }
249                    }
250            }
251    
252            /**
253             * This method adds a group to the list of groups with administrative
254             * privileges for the group.
255             * 
256             * @param groupID
257             *            ID of the group added to the group administrator list
258             */
259            public void addAdminGroupID(String groupID) throws MCRException {
260                    addAndUpdate(groupID, admGroupIDs);
261            }
262    
263            /**
264             * This method adds a user (ID) to the administrators list of the group
265             * 
266             * @param userID
267             *            ID of the administrative user added to the group
268             */
269            public void addAdminUserID(String userID) throws MCRException {
270                    addAndUpdate(userID, admUserIDs);
271            }
272    
273            /**
274             * This method adds a user (ID) to the users list of the group
275             * 
276             * @param userID
277             *            ID of the user added to the group
278             */
279            public void addMemberUserID(String userID) throws MCRException {
280                    addAndUpdate(userID, mbrUserIDs);
281            }
282    
283            /**
284             * @return This method returns the list of administrator groups as a ArrayList of
285             *         strings.
286             */
287            public final ArrayList<String> getAdminGroupIDs() {
288                    return admGroupIDs;
289            }
290    
291        /**
292         * This method set the list of administrator groups as a ArrayList of Strings.
293         */
294        public final void setAdminGroupIDs(ArrayList<String> array) {
295            admGroupIDs = array;
296        }
297    
298            /**
299             * @return This method returns the list of administrator users as a ArrayList of
300             *         strings.
301             */
302            public final ArrayList<String> getAdminUserIDs() {
303                    return admUserIDs;
304            }
305    
306        /**
307         * This method set the list of administrator users as a ArrayList of Strings.
308         */
309        public final void setAdminUserIDs(ArrayList<String> array) {
310            admUserIDs = array;
311        }
312    
313            /**
314             * @return This method returns the user list (group members) as a ArrayList
315             *         of strings.
316             */
317            public final ArrayList<String> getMemberUserIDs() {
318                    return mbrUserIDs;
319            }
320    
321            /**
322             * @return This method returns the ID (user ID or group ID) of the user
323             *         object.
324             */
325            public final String getID() {
326                    return ID;
327            }
328    
329            public final void setID(String value) {
330                    ID = value;
331            }
332    
333            /**
334             * This method checks if a user is a member of this group.
335             * 
336             * @param user
337             *            Is this user a member of the group?
338             * @return Returns true if the given user is a member of this group.
339             */
340            public boolean hasUserMember(MCRUser user) {
341                    if ((admUserIDs.contains(user.getID()))
342                                    || (mbrUserIDs.contains(user.getID()))) {
343                            return true;
344                    }
345    
346                    return false;
347            }
348    
349            /**
350             * This method checks if a user is a member of this group.
351             * 
352             * @param user
353             *            Is this user a member of the group?
354             * @return Returns true if the given user is a member of this group.
355             */
356            public boolean hasUserMember(String user) {
357                    if ((admUserIDs.contains(user)) || (mbrUserIDs.contains(user))) {
358                            return true;
359                    }
360    
361                    return false;
362            }
363    
364            /**
365             * This method checks if all required fields have been provided. In a later
366             * stage of the software development a User Policy object will be asked,
367             * which fields exactly are the required fields. This will be configurable.
368             * 
369             * @return returns true if all required fields have been provided
370             */
371            public boolean isValid() throws MCRException {
372                    ArrayList<String> requiredGroupAttributes = MCRUserPolicy.instance()
373                                    .getRequiredGroupAttributes();
374                    boolean test = true;
375    
376                    if (requiredGroupAttributes.contains("groupID")) {
377                            test = test && (super.ID.length() > 0);
378                    }
379    
380                    if (requiredGroupAttributes.contains("creator")) {
381                            test = test && (super.creator.length() > 0);
382                    }
383    
384                    return test;
385            }
386    
387            /**
388             * This method removes a group from the list of groups with administrative
389             * privileges for this group.
390             * 
391             * @param groupID
392             *            ID of the administrative group removed from the group
393             */
394            public void removeAdminGroupID(String groupID) throws MCRException {
395                    removeAndUpdate(groupID, admGroupIDs);
396            }
397    
398            /**
399             * This method remove all administrator group IDs.
400             */
401            public void removeAllAdminGroupID() {
402                admGroupIDs.clear();
403            }
404            
405            /**
406             * This method removes a user from the list of administrators of the group.
407             * 
408             * @param userID
409             *            ID of the administrative user removed from the group
410             */
411            public void removeAdminUserID(String userID) throws MCRException {
412                    removeAndUpdate(userID, admUserIDs);
413            }
414    
415        /**
416         * This method remove all administrator group IDs.
417         */
418        public void removeAllAdminUserID() {
419            admUserIDs.clear();
420        }
421        
422            /**
423             * This method removes a user from the users list (members) of the group.
424             * 
425             * @param userID
426             *            ID of the user removed from the group
427             */
428            public void removeMemberUserID(String userID) throws MCRException {
429                    removeAndUpdate(userID, mbrUserIDs);
430            }
431    
432        /**
433         * This method remove all administrator group IDs.
434         */
435        public void removeAllMemberUserID() {
436            mbrUserIDs.clear();
437        }
438        
439            /**
440             * @return This method returns the user or group object as a JDOM document.
441             */
442            public org.jdom.Document toJDOMDocument() throws MCRException {
443                    Element root = new Element("mycoregroup");
444                    root.addNamespaceDeclaration(XSI_NAMESPACE);
445                    root.addNamespaceDeclaration(XLINK_NAMESPACE);
446                    root.setAttribute("noNamespaceSchemaLocation", "MCRGroup.xsd",
447                                    XSI_NAMESPACE);
448                    root.addContent(this.toJDOMElement());
449    
450                    org.jdom.Document jdomDoc = new org.jdom.Document(root);
451    
452                    return jdomDoc;
453            }
454    
455            /**
456             * @return This method returns the user or group object as a JDOM element.
457             *         This is needed if one wants to get a representation of several
458             *         user or group objects in one xml document.
459             */
460            public Element toJDOMElement() {
461                    Element group = new Element("group").setAttribute("ID", ID);
462                    Element Creator = new Element("group.creator").setText(super.creator);
463                    Element CreationDate = new Element("group.creation_date")
464                                    .setText(super.creationDate.toString());
465                    Element ModifiedDate = new Element("group.last_modified")
466                                    .setText(super.modifiedDate.toString());
467                    Element Description = new Element("group.description")
468                                    .setText(super.description);
469                    Element admins = new Element("group.admins");
470                    Element members = new Element("group.members");
471    
472                    // Loop over all administrator user IDs
473                    for (int i = 0; i < admUserIDs.size(); i++) {
474                            Element admUserID = new Element("admins.userID")
475                                            .setText((String) admUserIDs.get(i));
476                            admins.addContent(admUserID);
477                    }
478    
479                    // Loop over all administrator group IDs
480                    for (int i = 0; i < admGroupIDs.size(); i++) {
481                            Element admGroupID = new Element("admins.groupID")
482                                            .setText((String) admGroupIDs.get(i));
483                            admins.addContent(admGroupID);
484                    }
485    
486                    // Loop over all user IDs (members of this group!)
487                    for (int i = 0; i < mbrUserIDs.size(); i++) {
488                            Element mbrUserID = new Element("members.userID")
489                                            .setText((String) mbrUserIDs.get(i));
490                            members.addContent(mbrUserID);
491                    }
492    
493                    // Aggregate group element
494                    group.addContent(Creator).addContent(CreationDate).addContent(
495                                    ModifiedDate).addContent(Description).addContent(admins)
496                                    .addContent(members);
497    
498                    return group;
499            }
500    
501            /**
502             * This method writes debug data to the logger (for the debug mode).
503             */
504            public final void debug() {
505                    debugDefault();
506    
507                    for (int i = 0; i < admGroupIDs.size(); i++) {
508                            logger.debug("admGroupIDs        = " + (String) admGroupIDs.get(i));
509                    }
510    
511                    for (int i = 0; i < admUserIDs.size(); i++) {
512                            logger.debug("admUserIDs         = " + (String) admUserIDs.get(i));
513                    }
514    
515                    for (int i = 0; i < mbrUserIDs.size(); i++) {
516                            logger.debug("mbrUserIDs         = " + (String) mbrUserIDs.get(i));
517                    }
518            }
519    
520            /**
521             * This private helper method adds values to a given vector. It is used by
522             * addGroupID etc.
523             * 
524             * @param s
525             *            String to be added to the vector vec
526             * @param vec
527             *            ArrayList to which the string s will be added to
528             */
529            private void addAndUpdate(String s, ArrayList<String> vec)
530                            throws MCRException {
531                            if (!vec.contains(s)) {
532                                    vec.add(s);
533                    }
534            }
535    
536            /**
537             * This private helper method removes values from a given vector. It is used
538             * by removeGroupID etc.
539             * 
540             * @param s
541             *            String to be removed from the vector vec
542             * @param vec
543             *            ArrayList from which the string s will be removed from
544             */
545            private void removeAndUpdate(String s, ArrayList<String> vec)
546                            throws MCRException {
547                            if (vec.contains(s)) {
548                                    vec.remove(s);
549                    }
550            }
551    
552    }