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, 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.ui.favorites;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsProject;
032import org.opencms.file.CmsResource;
033import org.opencms.file.CmsResourceFilter;
034import org.opencms.json.JSONException;
035import org.opencms.json.JSONObject;
036import org.opencms.main.CmsException;
037import org.opencms.main.OpenCms;
038import org.opencms.ui.A_CmsUI;
039import org.opencms.ui.CmsVaadinUtils;
040import org.opencms.ui.apps.A_CmsWorkplaceApp;
041import org.opencms.ui.apps.CmsFileExplorerConfiguration;
042import org.opencms.util.CmsStringUtil;
043import org.opencms.util.CmsUUID;
044
045/**
046 * Represents an entry in the favorite location list.
047 */
048public class CmsFavoriteEntry {
049
050    /**
051     * Represents the type of the favorite.
052     */
053    public enum Type {
054        /** Container page editor favorite. */
055        explorerFolder("f"),
056
057        /** Page favorite. */
058        page("p");
059
060        /** String representing this type in the JSON format. */
061        private String m_jsonId;
062
063        /**
064         * Creates new value.
065         *
066         * @param jsonId the JSON id.
067         */
068        private Type(String jsonId) {
069
070            m_jsonId = jsonId;
071
072        }
073
074        /**
075         * Converts JSON id to correct type.
076         *
077         * @param id the JSON id
078         * @return the corresponding type
079         */
080        public static Type fromJsonId(String id) {
081
082            for (Type type : Type.values()) {
083                if (type.getJsonId().equals(id)) {
084                    return type;
085                }
086            }
087            return null;
088        }
089
090        /**
091         * Gets the JSON id for the type.
092         *
093         * @return the JSON id
094         */
095        public String getJsonId() {
096
097            return m_jsonId;
098        }
099    }
100
101    /** JSON key. */
102    public static final String JSON_DETAIL = "d";
103
104    /** JSON key. */
105    public static final String JSON_PROJECT = "p";
106
107    /** JSON key. */
108    public static final String JSON_SITEROOT = "s";
109
110    /** JSON key. */
111    public static final String JSON_STRUCTUREID = "i";
112
113    /** JSON key. */
114    public static final String JSON_TITLE = "ti";
115
116    /** JSON key. */
117    public static final String JSON_TYPE = "t";
118
119    /** The custom title. */
120    private String m_customTitle;
121
122    /** The detail id. */
123    private CmsUUID m_detailId;
124
125    /** The project id. */
126    private CmsUUID m_projectId;
127
128    /** The site root. */
129    private String m_siteRoot;
130
131    /** The structure id. */
132    private CmsUUID m_structureId;
133
134    /** The type. */
135    private Type m_type;
136
137    /**
138     * Creates a new entry.
139     */
140    public CmsFavoriteEntry() {}
141
142    /**
143     * Creates a new entry from a JSON object.
144     *
145     * @param obj the JSON object
146     */
147    public CmsFavoriteEntry(JSONObject obj) {
148
149        m_detailId = readId(obj, JSON_DETAIL);
150        m_projectId = readId(obj, JSON_PROJECT);
151        setSiteRoot(obj.optString(JSON_SITEROOT));
152        m_structureId = readId(obj, JSON_STRUCTUREID);
153        m_type = Type.fromJsonId(obj.optString(JSON_TYPE));
154        m_customTitle = obj.optString(JSON_TITLE);
155    }
156
157    /**
158     * Reads a UUID from a JSON object.
159     *
160     * Returns null if the JSON value for the given key is not present or not a valid UUID
161     *
162     * @param obj the JSON object
163     * @param key the JSON key
164     *
165     * @return the UUID
166     */
167    public static CmsUUID readId(JSONObject obj, String key) {
168
169        String strValue = obj.optString(key);
170        if (!CmsUUID.isValidUUID(strValue)) {
171            return null;
172        }
173        return new CmsUUID(strValue);
174    }
175
176    /**
177     * Gets the custom title.
178     *
179     * @return the custom title
180     */
181    public String getCustomTitle() {
182
183        return m_customTitle;
184    }
185
186    /**
187     * Gets the detail id.
188     *
189     * @return the detail id
190     */
191    public CmsUUID getDetailId() {
192
193        return m_detailId;
194    }
195
196    /**
197     * Gets the project id.
198     *
199     * @return the project id
200     */
201    public CmsUUID getProjectId() {
202
203        return m_projectId;
204    }
205
206    /**
207     * Gets the site root.
208     *
209     * @return the site root
210     */
211    public String getSiteRoot() {
212
213        return m_siteRoot;
214    }
215
216    /**
217     * Gets the structure id
218     *
219     * @return the structure id
220     */
221    public CmsUUID getStructureId() {
222
223        return m_structureId;
224    }
225
226    /**
227     * Gets the type.
228     *
229     * @return the type
230     */
231    public Type getType() {
232
233        return m_type;
234    }
235
236    /**
237     * Sets the custom title.
238     *
239     * @param title the custom title
240     */
241    public void setCustomTitle(String title) {
242
243        if (CmsStringUtil.isEmpty(title)) {
244            m_customTitle = null;
245        } else {
246            m_customTitle = title;
247        }
248    }
249
250    /**
251     * Sets the detail id.
252     *
253     * @param detailId the detail id
254     */
255    public void setDetailId(CmsUUID detailId) {
256
257        m_detailId = detailId;
258    }
259
260    /**
261     * Sets the project id.
262     *
263     * @param projectId the project id
264     */
265    public void setProjectId(CmsUUID projectId) {
266
267        m_projectId = projectId;
268    }
269
270    /**
271     * Sets the site root.
272     *
273     * @param siteRoot the site root
274     */
275    public void setSiteRoot(String siteRoot) {
276
277        if (siteRoot != null) {
278            siteRoot = siteRoot.replaceFirst("/$", "");
279        }
280        m_siteRoot = siteRoot;
281    }
282
283    /**
284     * Sets the structure id.
285     * @param structureId the structure id
286     */
287    public void setStructureId(CmsUUID structureId) {
288
289        m_structureId = structureId;
290    }
291
292    /**
293     * Sets the type.
294     *
295     * @param type the type
296     */
297    public void setType(Type type) {
298
299        m_type = type;
300    }
301
302    /**
303     * Converts this object to JSON.
304     *
305     * @return the JSON representation
306     *
307     * @throws JSONException if JSON operations fail
308     */
309    public JSONObject toJson() throws JSONException {
310
311        JSONObject result = new JSONObject();
312        if (m_detailId != null) {
313            result.put(JSON_DETAIL, "" + m_detailId);
314        }
315        if (m_siteRoot != null) {
316            result.put(JSON_SITEROOT, m_siteRoot);
317        }
318        if (m_structureId != null) {
319            result.put(JSON_STRUCTUREID, "" + m_structureId);
320        }
321        if (m_projectId != null) {
322            result.put(JSON_PROJECT, "" + m_projectId);
323        }
324        if (m_type != null) {
325            result.put(JSON_TYPE, "" + m_type.getJsonId());
326        }
327
328        if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_customTitle)) {
329            result.put(JSON_TITLE, m_customTitle);
330        }
331        return result;
332    }
333
334    /**
335     * Prepares the CmsObject for jumping to this favorite location, and returns the appropriate URL.
336     *
337     * @param cms the CmsObject to initialize for jumping to the favorite
338     * @return the link for the favorite location
339     *
340     * @throws CmsException if something goes wrong
341     */
342    public String updateContextAndGetFavoriteUrl(CmsObject cms) throws CmsException {
343
344        CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION;
345        CmsProject project = null;
346        switch (getType()) {
347            case explorerFolder:
348                CmsResource folder = cms.readResource(getStructureId(), filter);
349                project = cms.readProject(getProjectId());
350                cms.getRequestContext().setSiteRoot(getSiteRoot());
351                A_CmsUI.get().getWorkplaceSettings().setSite(getSiteRoot());
352                cms.getRequestContext().setCurrentProject(project);
353                String explorerLink = CmsVaadinUtils.getWorkplaceLink(
354                    CmsFileExplorerConfiguration.APP_ID,
355                    getProjectId()
356                        + A_CmsWorkplaceApp.PARAM_SEPARATOR
357                        + getSiteRoot()
358                        + A_CmsWorkplaceApp.PARAM_SEPARATOR
359                        + cms.getSitePath(folder));
360                return explorerLink;
361            case page:
362                project = cms.readProject(getProjectId());
363                CmsResource target = cms.readResource(getStructureId(), filter);
364                CmsResource detailContent = null;
365                String link = null;
366                cms.getRequestContext().setCurrentProject(project);
367                cms.getRequestContext().setSiteRoot(getSiteRoot());
368                A_CmsUI.get().getWorkplaceSettings().setSite(getSiteRoot());
369                if (getDetailId() != null) {
370                    detailContent = cms.readResource(getDetailId());
371                    link = OpenCms.getLinkManager().substituteLinkForUnknownTarget(
372                        cms,
373                        cms.getSitePath(detailContent),
374                        cms.getSitePath(target),
375                        false);
376                } else {
377                    link = OpenCms.getLinkManager().substituteLink(cms, target);
378                }
379                return link;
380            default:
381                return null;
382        }
383    }
384
385}