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