001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.file;
029
030import org.opencms.main.CmsIllegalArgumentException;
031import org.opencms.security.CmsOrganizationalUnit;
032import org.opencms.util.A_CmsModeIntEnumeration;
033import org.opencms.util.CmsStringUtil;
034import org.opencms.util.CmsUUID;
035
036import java.util.List;
037
038/**
039 * Describes an OpenCms project,
040 * which contains a set of VFS resources that are being worked on at the same time.<p>
041 *
042 * @since 6.0.0
043 */
044public class CmsProject implements Cloneable, Comparable<CmsProject> {
045
046    /**
047     *  Enumeration class for project types.<p>
048     */
049    public static final class CmsProjectType extends A_CmsModeIntEnumeration {
050
051        /** Project type normal. */
052        protected static final CmsProjectType MODE_PROJECT_NORMAL = new CmsProjectType(0);
053
054        /** Project type temporary. */
055        protected static final CmsProjectType MODE_PROJECT_TEMPORARY = new CmsProjectType(1);
056
057        /** Project type 'workflow'. */
058        protected static final CmsProjectType MODE_PROJECT_WORKFLOW = new CmsProjectType(2);
059
060        /** Serializable version id. */
061        private static final long serialVersionUID = -8701314451776599534L;
062
063        /**
064         * Private constructor.<p>
065         *
066         * @param mode the copy mode integer representation
067         */
068        private CmsProjectType(int mode) {
069
070            super(mode);
071        }
072
073        /**
074         * Returns the copy mode object from the old copy mode integer.<p>
075         *
076         * @param mode the old copy mode integer
077         *
078         * @return the copy mode object
079         */
080        public static CmsProjectType valueOf(int mode) {
081
082            switch (mode) {
083                case 0:
084                    return CmsProjectType.MODE_PROJECT_NORMAL;
085                case 1:
086                    return CmsProjectType.MODE_PROJECT_TEMPORARY;
087                case 2:
088                    return CmsProjectType.MODE_PROJECT_WORKFLOW;
089                default:
090                    return CmsProjectType.MODE_PROJECT_NORMAL;
091            }
092        }
093
094        /**
095         * Returns the default flags which should be set when a new project of this type is created.<p>
096         *
097         * @return the default flags for the project type
098         */
099        public int getDefaultFlags() {
100
101            //            if (getMode() == CmsProjectType.MODE_PROJECT_WORKFLOW.getMode()) {
102            //                return PROJECT_FLAG_HIDDEN;
103            //            }
104            return PROJECT_FLAG_NONE;
105        }
106    }
107
108    /** The name of the online project. */
109    public static final String ONLINE_PROJECT_NAME = "Online";
110
111    /** The id of the online project. */
112    public static final CmsUUID ONLINE_PROJECT_ID = CmsUUID.getConstantUUID(ONLINE_PROJECT_NAME);
113
114    /** Indicates that a project is invisible in the workplace. */
115    public static final int PROJECT_FLAG_HIDDEN = 4;
116
117    /** Indicates that a normal project. */
118    public static final int PROJECT_FLAG_NONE = 0;
119
120    /** Indicates that a project should be hidden from the workplace project selector, but should otherwise behave the same as normal projects. */
121    public static final int PROJECT_HIDDEN_IN_SELECTOR = 8;
122
123    /** Indicates a normal project. */
124    public static final CmsProjectType PROJECT_TYPE_NORMAL = CmsProjectType.MODE_PROJECT_NORMAL;
125
126    /** The project type for a workflow project. */
127    public static final CmsProjectType PROJECT_TYPE_WORKFLOW = CmsProjectType.MODE_PROJECT_WORKFLOW;
128
129    /** Indicates a temporary project that is deleted after it is published. */
130    public static final CmsProjectType PROJECT_TYPE_TEMPORARY = CmsProjectType.MODE_PROJECT_TEMPORARY;
131
132    /** The creation date of this project. */
133    private long m_dateCreated;
134
135    /** The description of this project. */
136    private String m_description;
137
138    /** The state of this project. */
139    private int m_flags;
140
141    /** The manager group id of this project. */
142    private CmsUUID m_groupManagersId;
143
144    /** The id of the user group of this project. */
145    private CmsUUID m_groupUsersId;
146
147    /** The id of this project. */
148    private CmsUUID m_id;
149
150    /** The name of this project. */
151    private String m_name;
152
153    /** The id of this projects owner. */
154    private CmsUUID m_ownerId;
155
156    /** The type of this project. */
157    private CmsProjectType m_type;
158
159    /**
160     * Default constructor for gui usage.<p>
161     */
162    public CmsProject() {
163
164        // empty
165    }
166
167    /**
168     * Creates a new CmsProject.<p>
169     *
170     * @param projectId the id to use for this project
171     * @param projectFqn the name for this project
172     * @param description the description for this project
173     * @param ownerId the owner id for this project
174     * @param groupId the group id for this project
175     * @param managerGroupId the manager group id for this project
176     * @param flags the flags for this project
177     * @param dateCreated the creation date of this project
178     * @param type the type of this project
179     */
180    public CmsProject(
181        CmsUUID projectId,
182        String projectFqn,
183        String description,
184        CmsUUID ownerId,
185        CmsUUID groupId,
186        CmsUUID managerGroupId,
187        int flags,
188        long dateCreated,
189        CmsProjectType type) {
190
191        m_id = projectId;
192        m_name = projectFqn;
193        m_description = description;
194        m_ownerId = ownerId;
195        m_groupUsersId = groupId;
196        m_groupManagersId = managerGroupId;
197        m_flags = flags;
198        m_type = type;
199        m_dateCreated = dateCreated;
200    }
201
202    /**
203     * Throws a runtime exception if name is empty.<p>
204     *
205     * @param name the project name to check
206     */
207    public static void checkProjectName(String name) {
208
209        if (CmsStringUtil.isEmptyOrWhitespaceOnly(name)) {
210            throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_PROJECTNAME_VALIDATION_0));
211        }
212    }
213
214    /**
215     * Checks if the full resource name (including the site root) of a resource matches
216     * any of the project resources of a project.<p>
217     *
218     * @param projectResources a List of project resources as Strings
219     * @param resource the resource to check
220     * @return true, if the resource is "inside" the project resources
221     */
222    public static boolean isInsideProject(List<String> projectResources, CmsResource resource) {
223
224        String resourcename = resource.getRootPath();
225        return isInsideProject(projectResources, resourcename);
226    }
227
228    /**
229     * Checks if the full resource name (including the site root) of a resource matches
230     * any of the project resources of a project.<p>
231     *
232     * @param projectResources a List of project resources as Strings
233     * @param resourcename the resource to check
234     * @return true, if the resource is "inside" the project resources
235     */
236    public static boolean isInsideProject(List<String> projectResources, String resourcename) {
237
238        for (int i = (projectResources.size() - 1); i >= 0; i--) {
239            String projectResource = projectResources.get(i);
240            if (CmsResource.isFolder(projectResource)) {
241                if (resourcename.startsWith(projectResource)) {
242                    // folder - check only the prefix
243                    return true;
244                }
245            } else {
246                if (resourcename.equals(projectResource)) {
247                    // file - check the full path
248                    return true;
249                }
250            }
251        }
252        return false;
253    }
254
255    /**
256     * Returns true if the given project id is the online project id.<p>
257     *
258     * @param projectId the project id to check
259     * @return true if the given project id is the online project id
260     */
261    public static boolean isOnlineProject(CmsUUID projectId) {
262
263        return projectId.equals(CmsProject.ONLINE_PROJECT_ID);
264    }
265
266    /**
267     * @see java.lang.Object#clone()
268     */
269    @Override
270    public Object clone() {
271
272        return new CmsProject(
273            m_id,
274            m_name,
275            m_description,
276            m_ownerId,
277            m_groupUsersId,
278            m_groupManagersId,
279            m_flags,
280            m_dateCreated,
281            m_type);
282    }
283
284    /**
285     * Compares this instance to another given object instance of this class .<p>
286     *
287     * @param o the other given object instance to compare with
288     * @return integer value for sorting the objects
289     */
290    public int compareTo(CmsProject o) {
291
292        if (o == this) {
293            return 0;
294        }
295
296        // compare the names
297        return m_name.compareTo(o.getName());
298    }
299
300    /**
301     * @see java.lang.Object#equals(java.lang.Object)
302     */
303    @Override
304    public boolean equals(Object obj) {
305
306        if (obj == this) {
307            return true;
308        }
309        if (obj instanceof CmsProject) {
310            return ((CmsProject)obj).m_id.equals(m_id);
311        }
312        return false;
313    }
314
315    /**
316     * Returns the creation date of this project.<p>
317     *
318     * @return the creation date of this project
319     */
320    public long getDateCreated() {
321
322        return m_dateCreated;
323    }
324
325    /**
326     * Returns the description of this project.
327     *
328     * @return the description of this project
329     */
330    public String getDescription() {
331
332        return m_description;
333    }
334
335    /**
336     * Returns the state of this project.<p>
337     *
338     * @return the state of this project
339     */
340    public int getFlags() {
341
342        return m_flags;
343    }
344
345    /**
346     * Returns the user group id of this project.<p>
347     *
348     * @return the user group id of this project
349     */
350    public CmsUUID getGroupId() {
351
352        return m_groupUsersId;
353    }
354
355    /**
356     * Returns the manager group id of this project.<p>
357     *
358     * @return the manager group id of this project
359     */
360    public CmsUUID getManagerGroupId() {
361
362        return m_groupManagersId;
363    }
364
365    /**
366     * Returns the name of this project.<p>
367     *
368     * @return the name of this project
369     */
370    public String getName() {
371
372        return m_name;
373    }
374
375    /**
376     * Returns the fully qualified name of the associated organizational unit.<p>
377     *
378     * @return the fully qualified name of the associated organizational unit
379     */
380    public String getOuFqn() {
381
382        return CmsOrganizationalUnit.getParentFqn(m_name);
383    }
384
385    /**
386     * Returns the user id of the project owner.<p>
387     *
388     * @return the user id of the project owner
389     */
390    public CmsUUID getOwnerId() {
391
392        return m_ownerId;
393    }
394
395    /**
396     * Returns the simple name of this organizational unit.
397     *
398     * @return the simple name of this organizational unit.
399     */
400    public String getSimpleName() {
401
402        return CmsOrganizationalUnit.getSimpleName(m_name);
403    }
404
405    /**
406     * Returns the type of this project.<p>
407     *
408     * @return the type of this project
409     */
410    public CmsProjectType getType() {
411
412        return m_type;
413    }
414
415    /**
416     * Returns the id of this project.<p>
417     *
418     * @return the id of this project
419     */
420    public CmsUUID getUuid() {
421
422        return m_id;
423    }
424
425    /**
426     * @see java.lang.Object#hashCode()
427     */
428    @Override
429    public int hashCode() {
430
431        if (m_name != null) {
432            return m_name.hashCode();
433        }
434        return 0;
435    }
436
437    /**
438     * Returns the delete After Publishing flag.<p>
439     *
440     * @return the delete After Publishing flag
441     *
442     * @see #getType()
443     */
444    public boolean isDeleteAfterPublishing() {
445
446        return (m_type == CmsProject.PROJECT_TYPE_TEMPORARY);
447    }
448
449    /**
450     * Returns the 'hidden' flag.<p>
451     *
452     * @return the 'hidden' flag
453     *
454     * @see #getFlags()
455     */
456    public boolean isHidden() {
457
458        return (getFlags() & PROJECT_FLAG_HIDDEN) == PROJECT_FLAG_HIDDEN;
459    }
460
461    /**
462     * Checks if the project should be hidden from the project selector in the workplace.<p>
463     *
464     * @return true if the project should not appear in the workplace's project selector
465     */
466    public boolean isHiddenFromSelector() {
467
468        return isWorkflowProject() || (0 != (getFlags() & PROJECT_HIDDEN_IN_SELECTOR));
469    }
470
471    /**
472     * Returns <code>true</code> if this project is the Online project.<p>
473     *
474     * @return <code>true</code> if this project is the Online project
475     */
476    public boolean isOnlineProject() {
477
478        return isOnlineProject(m_id);
479    }
480
481    /**
482     * Returns true if this is a workflow project.<p>
483     *
484     * @return true if this is a workflow project
485     */
486    public boolean isWorkflowProject() {
487
488        return getType().getMode() == PROJECT_TYPE_WORKFLOW.getMode();
489    }
490
491    /**
492     * Sets the delete After Publishing flag.<p>
493     *
494     * @param deleteAfterPublishing the delete After Publishing flag to set
495     */
496    public void setDeleteAfterPublishing(boolean deleteAfterPublishing) {
497
498        m_type = deleteAfterPublishing ? CmsProject.PROJECT_TYPE_TEMPORARY : CmsProject.PROJECT_TYPE_NORMAL;
499    }
500
501    /**
502     * Sets the description of this project.<p>
503     *
504     * @param description the description to set
505     */
506    public void setDescription(String description) {
507
508        m_description = description;
509    }
510
511    /**
512     * Sets the flags of this project.<p>
513     *
514     * @param flags the flag to set
515     */
516    public void setFlags(int flags) {
517
518        m_flags = flags;
519    }
520
521    /**
522     * Sets the user group id of this project.<p>
523     *
524     * @param id the user group id of this project
525     */
526    public void setGroupId(CmsUUID id) {
527
528        CmsUUID.checkId(id, false);
529        m_groupUsersId = id;
530    }
531
532    /**
533     * Sets the 'hidden' flag.<p>
534     *
535     * @param value the value to set
536     */
537    public void setHidden(boolean value) {
538
539        if (isHidden() != value) {
540            setFlags(getFlags() ^ PROJECT_FLAG_HIDDEN);
541        }
542    }
543
544    /**
545     * Sets the manager group id of this project.<p>
546     *
547     * @param id the manager group id of this project
548     */
549    public void setManagerGroupId(CmsUUID id) {
550
551        CmsUUID.checkId(id, false);
552        m_groupManagersId = id;
553    }
554
555    /**
556     * Sets the name.<p>
557     *
558     * @param name the name to set
559     */
560    public void setName(String name) {
561
562        checkProjectName(name);
563        m_name = name;
564    }
565
566    /**
567     * Sets the owner id of this project.<p>
568     *
569     * @param id the id of the new owner
570     */
571    public void setOwnerId(CmsUUID id) {
572
573        CmsUUID.checkId(id, false);
574        m_ownerId = id;
575    }
576
577    /**
578     * @see java.lang.Object#toString()
579     */
580    @Override
581    public String toString() {
582
583        StringBuffer result = new StringBuffer();
584        result.append("[Project]:");
585        result.append(m_name);
586        result.append(" , Id=");
587        result.append(m_id);
588        result.append(", Desc=");
589        result.append(m_description);
590        return result.toString();
591    }
592
593    /**
594     * Sets the type of this project.<p>
595     *
596     * @param type the type to set
597     */
598    void setType(CmsProjectType type) {
599
600        m_type = type;
601    }
602}