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.db;
029
030import org.opencms.file.CmsResource;
031import org.opencms.util.CmsUUID;
032
033import java.io.Serializable;
034
035/**
036 * Represents the state of a published resource *before* it got published.<p>
037 *
038 * This allows various subsequent tasks in the Cms app. (e.g. exporting files and folders)
039 * to identify published resources after a resource or project was published.<p>
040 *
041 * The values to fill this container are read from the Cms publish history database table
042 * that is written during each publishing process.<p>
043 *
044 * @since 6.0.0
045 *
046 * @see org.opencms.db.I_CmsProjectDriver#readPublishedResources(CmsDbContext, CmsUUID)
047 */
048public class CmsPublishedResource implements Serializable, Comparable<CmsPublishedResource> {
049
050    /**
051     * Add new resource states under consideration of the move operation.<p>
052     */
053    public static class CmsPublishedResourceState extends CmsResourceState {
054
055        /** The serial version id. */
056        private static final long serialVersionUID = -2901049208546972463L;
057
058        /**
059         * protected constructor.<p>
060         *
061         * @param state an integer representing the state
062         * @param abbrev an abbreviation character
063         */
064        protected CmsPublishedResourceState(int state, char abbrev) {
065
066            super(state, abbrev);
067        }
068
069        /**
070         * Returns the corresponding resource state for this publish resource state.<p>
071         *
072         * @return the corresponding resource state
073         */
074        public CmsResourceState getResourceState() {
075
076            if (this == STATE_MOVED_SOURCE) {
077                return CmsResource.STATE_DELETED;
078            } else if (this == STATE_MOVED_DESTINATION) {
079                return CmsResource.STATE_NEW;
080            } else {
081                return null;
082            }
083        }
084    }
085
086    /** Additional state for moved resources, the (new) destination of the moved resource. */
087    public static final CmsPublishedResourceState STATE_MOVED_DESTINATION = new CmsPublishedResourceState(12, 'M');
088
089    /** Additional state for moved resources, the (deleted) source of the moved resource. */
090    public static final CmsPublishedResourceState STATE_MOVED_SOURCE = new CmsPublishedResourceState(11, ' ');
091
092    /** Serial version UID required for safe serialization. */
093    private static final long serialVersionUID = -1054065812825770479L;
094
095    /** Indicates if the published resource is a folder or a file. */
096    private boolean m_isFolder;
097
098    /** Flag to signal if the resource was moved. */
099    private boolean m_isMoved;
100
101    /** The publish tag of the published resource. */
102    private int m_publishTag;
103
104    /** The resource ID of the published resource.<p> */
105    private CmsUUID m_resourceId;
106
107    /** The state of the resource *before* it was published.<p> */
108    private CmsResourceState m_resourceState;
109
110    /** The type of the published resource.<p> */
111    private int m_resourceType;
112
113    /** The root path of the published resource.<p> */
114    private String m_rootPath;
115
116    /** The count of siblings of the published resource. */
117    private int m_siblingCount;
118
119    /** The structure ID of the published resource.<p> */
120    private CmsUUID m_structureId;
121
122    /**
123     * Creates an object for published VFS resources.<p>
124     *
125     * Do not write objects created with this constructor to db, since the publish tag is not set.<p>
126     *
127     * @param resource an CmsResource object to create a CmsPublishedResource from
128     */
129    public CmsPublishedResource(CmsResource resource) {
130
131        this(resource, -1);
132    }
133
134    /**
135     * Creates an object for published VFS resources.<p>
136     *
137     * @param resource an CmsResource object to create a CmsPublishedResource from
138     * @param publishTag the publish Tag
139     */
140    public CmsPublishedResource(CmsResource resource, int publishTag) {
141
142        this(resource, publishTag, resource.getState());
143    }
144
145    /**
146     * Creates an object for published VFS resources.<p>
147     *
148     * @param resource an CmsResource object to create a CmsPublishedResource from
149     * @param state the resource state
150     * @param publishTag the publish tag
151     */
152    public CmsPublishedResource(CmsResource resource, int publishTag, CmsResourceState state) {
153
154        this(
155            resource.getStructureId(),
156            resource.getResourceId(),
157            publishTag,
158            resource.getRootPath(),
159            resource.getTypeId(),
160            resource.isFolder(),
161            state,
162            resource.getSiblingCount());
163    }
164
165    /**
166     * Creates an object for published VFS resources.<p>
167     *
168     * @param structureId the structure ID of the published resource
169     * @param resourceId the resource ID of the published resource
170     * @param publishTag the publish tag
171     * @param rootPath the root path of the published resource
172     * @param resourceType the type of the published resource
173     * @param isFolder indicates if the published resource is a folder or a file
174     * @param resourceState the state of the resource *before* it was published
175     * @param siblingCount count of siblings of the published resource
176     */
177    public CmsPublishedResource(
178        CmsUUID structureId,
179        CmsUUID resourceId,
180        int publishTag,
181        String rootPath,
182        int resourceType,
183        boolean isFolder,
184        CmsResourceState resourceState,
185        int siblingCount) {
186
187        m_structureId = structureId;
188        m_resourceId = resourceId;
189        m_publishTag = publishTag;
190        m_rootPath = rootPath;
191        m_resourceType = resourceType;
192        m_isFolder = isFolder;
193        if (resourceState instanceof CmsPublishedResourceState) {
194            m_resourceState = ((CmsPublishedResourceState)resourceState).getResourceState();
195            m_isMoved = true;
196        } else {
197            m_resourceState = resourceState;
198        }
199        m_siblingCount = siblingCount;
200    }
201
202    /**
203     * @see java.lang.Comparable#compareTo(java.lang.Object)
204     */
205    public int compareTo(CmsPublishedResource obj) {
206
207        if (obj == this) {
208            return 0;
209        }
210        if (m_rootPath != null) {
211            return m_rootPath.compareTo(obj.m_rootPath);
212        }
213        return 0;
214    }
215
216    /**
217     * @see java.lang.Object#equals(java.lang.Object)
218     */
219    @Override
220    public boolean equals(Object obj) {
221
222        if (obj == this) {
223            return true;
224        }
225        if (obj instanceof CmsPublishedResource) {
226            if (m_structureId.isNullUUID()) {
227                return ((CmsPublishedResource)obj).m_resourceId.equals(m_resourceId);
228            } else {
229                return ((CmsPublishedResource)obj).m_structureId.equals(m_structureId);
230            }
231        }
232        return false;
233    }
234
235    /**
236     * Returns the resource state including move operation information.<p>
237     *
238     * @return the resource state including move operation information
239     */
240    public CmsResourceState getMovedState() {
241
242        if (!m_isMoved) {
243            return getState();
244        } else if (getState().isDeleted()) {
245            return STATE_MOVED_SOURCE;
246        } else if (getState().isNew()) {
247            return STATE_MOVED_DESTINATION;
248        } else {
249            // should never happen
250            return getState();
251        }
252    }
253
254    /**
255     * Returns the publish tag of the published resource.<p>
256     *
257     * @return the publish tag of the published resource
258     */
259    public int getPublishTag() {
260
261        return m_publishTag;
262    }
263
264    /**
265     * Returns the resource ID of the published resource.<p>
266     *
267     * @return the resource ID of the published resource
268     */
269    public CmsUUID getResourceId() {
270
271        return m_resourceId;
272    }
273
274    /**
275     * Returns the root path of the published resource.<p>
276     *
277     * @return the root path of the published resource
278     */
279    public String getRootPath() {
280
281        return m_rootPath;
282    }
283
284    /**
285     * Returns the count of siblings of the published resource.<p>
286     *
287     * If a resource has no sibling, the total sibling count for this resource is <code>1</code>,
288     * if a resource has <code>n</code> siblings, the sibling count is <code>n + 1</code>.<p>
289     *
290     * @return the count of siblings of the published resource
291     */
292    public int getSiblingCount() {
293
294        return m_siblingCount;
295    }
296
297    /**
298     * Returns the resource state of the published resource.<p>
299     *
300     * @return the resource state of the published resource
301     */
302    public CmsResourceState getState() {
303
304        return m_resourceState;
305    }
306
307    /**
308     * Returns the structure ID of the published resource.<p>
309     *
310     * @return the structure ID of the published resource
311     */
312    public CmsUUID getStructureId() {
313
314        return m_structureId;
315    }
316
317    /**
318     * Returns the resource type of the published resource.<p>
319     *
320     * @return the resource type of the published resource
321     */
322    public int getType() {
323
324        return m_resourceType;
325    }
326
327    /**
328     * @see java.lang.Object#hashCode()
329     */
330    @Override
331    public int hashCode() {
332
333        return m_structureId.isNullUUID() ? m_resourceId.hashCode() : m_structureId.hashCode();
334    }
335
336    /**
337     * Determines if this resource is a file.<p>
338     *
339     * @return true if this resource is a file, false otherwise
340     */
341    public boolean isFile() {
342
343        return !m_isFolder;
344    }
345
346    /**
347     * Checks if this resource is a folder.<p>
348     *
349     * @return true if this is is a folder
350     */
351    public boolean isFolder() {
352
353        return m_isFolder;
354    }
355
356    /**
357     * Returns <code>true</code> if the resource has been moved.<p>
358     *
359     * @return <code>true</code> if the resource has been moved
360     */
361    public boolean isMoved() {
362
363        return m_isMoved;
364    }
365
366    /**
367     * Sets the resource state of the published resource.<p>
368     *
369     * This is sometimes required for offline search index generation.<p>
370     *
371     * @param state the new state to set
372     */
373    public void setState(CmsResourceState state) {
374
375        m_resourceState = state;
376    }
377
378    /**
379     * @see java.lang.Object#toString()
380     */
381    @Override
382    public String toString() {
383
384        StringBuffer result = new StringBuffer(128);
385
386        result.append("[");
387        result.append(this.getClass().getName());
388        result.append(": root path: ");
389        result.append(m_rootPath);
390        result.append(", structure ID: ");
391        result.append(m_structureId);
392        result.append(", resource ID: ");
393        result.append(m_resourceId);
394        result.append(", publish tag: ");
395        result.append(m_publishTag);
396        result.append(", siblings: ");
397        result.append(m_siblingCount);
398        result.append(", state: ");
399        result.append(m_resourceState);
400        result.append(", type: ");
401        result.append(m_resourceType);
402        result.append("]");
403
404        return result.toString();
405    }
406}