/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.workplace.galleries; import org.opencms.db.CmsResourceState; import org.opencms.file.CmsObject; import org.opencms.file.CmsProperty; import org.opencms.file.CmsPropertyDefinition; import org.opencms.file.CmsResource; import org.opencms.file.CmsResourceFilter; import org.opencms.file.types.CmsResourceTypeFolderExtended; import org.opencms.i18n.CmsMessageContainer; import org.opencms.json.JSONArray; import org.opencms.json.JSONException; import org.opencms.json.JSONObject; import org.opencms.jsp.CmsJspActionElement; import org.opencms.lock.CmsLock; import org.opencms.main.CmsException; import org.opencms.main.CmsLog; import org.opencms.main.CmsRuntimeException; import org.opencms.main.OpenCms; import org.opencms.relations.CmsCategory; import org.opencms.relations.CmsCategoryService; import org.opencms.security.CmsPermissionSet; import org.opencms.util.CmsStringUtil; import org.opencms.workplace.CmsDialog; import org.opencms.workplace.CmsWorkplace; import org.opencms.workplace.CmsWorkplaceManager; import org.opencms.workplace.CmsWorkplaceSettings; import org.opencms.workplace.commons.CmsPreferences; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import org.apache.commons.logging.Log; /** * Provides the general helper methods to generate the content of a gallery dialog used in the XML content editors, * WYSIWYG editors and context menu. It <p> * * It is also used for AJAX requests to dynamically switch galleries or categories and get additional information * for the currently active item of the dialog.<p> * * Extend this class for every gallery type (e.g. image gallery or download gallery) to build.<p> * * @since 7.5.0 */ public abstract class A_CmsAjaxGallery extends CmsDialog { /** Request parameter value for the action: change the item link url value. */ public static final String DIALOG_CHANGEITEMLINKURL = "changeitemlinkurl"; /** Request parameter value for the action: change the item title property value. */ public static final String DIALOG_CHANGEITEMTITLE = "changeitemtitle"; /** Request parameter value for the action: get the currently active item object. */ public static final String DIALOG_GETACTIVEITEM = "getactiveitem"; /** Request parameter value for the action: get the category selection list. */ public static final String DIALOG_GETCATEGORIES = "getcategories"; /** Request parameter value for the action: get the gallery selection list. */ public static final String DIALOG_GETGALLERIES = "getgalleries"; /** Request parameter value for the action: get a specific gallery. */ public static final String DIALOG_GETGALLERY = "getgallery"; /** Request parameter value for the action: get the items for a gallery or category. */ public static final String DIALOG_GETITEMS = "getitems"; /** Request parameter value for the action: list gallery items. */ public static final String DIALOG_LIST = "list"; /** The list mode name "category" for getting the items. */ public static final String LISTMODE_CATEGORY = "category"; /** The list mode name "gallery" for getting the items. */ public static final String LISTMODE_GALLERY = "gallery"; /** Request parameter value for the dialog mode: editor. */ public static final String MODE_EDITOR = "editor"; /** Request parameter value for the dialog mode: view. */ public static final String MODE_VIEW = "view"; /** Request parameter value for the dialog mode: widget. */ public static final String MODE_WIDGET = "widget"; /** Request parameter name for the dialog mode (widget or editor). */ public static final String PARAM_DIALOGMODE = "dialogmode"; /** Request parameter name for the edited resource. */ public static final String PARAM_EDITEDRESOURCE = "editedresource"; /** Request parameter name for the input field id. */ public static final String PARAM_FIELDID = "fieldid"; /** Request parameter name for the gallery path. */ public static final String PARAM_GALLERYPATH = "gallerypath"; /** Request parameter name for the active item path. */ public static final String PARAM_ITEMPATH = "itempath"; /** Request parameter name for the dialog initialization parameters. */ public static final String PARAM_PARAMS = "params"; /** Request parameter name for the startup folder. */ public static final String PARAM_STARTUPFOLDER = "startupfolder"; /** Request parameter name for the startup type. */ public static final String PARAM_STARTUPTYPE = "startuptype"; /** The galleries path in the workplace containing the JSPs. */ public static final String PATH_GALLERIES = CmsWorkplace.VFS_PATH_WORKPLACE + "galleries/"; /** Value that is returned if no result was found. */ public static final String RETURNVALUE_NONE = "none"; /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(A_CmsAjaxGallery.class); /** The optional parameters for the gallery from the XML configuration. */ protected String m_galleryTypeParams; /** The gallery items to display. */ private List<CmsResource> m_galleryItems; /** The dialog mode the gallery is running in. */ private String m_paramDialogMode; /** The input field id that is required when in widget mode. */ private String m_paramFieldId; /** The current gallery path. */ private String m_paramGalleryPath; /** The list mode to get the item either from a gallery or by a category. */ private String m_paramListMode; /** The value of the property (current property definition: Title). */ private String m_paramPropertyValue; /** The gallery base resource type. */ private CmsResourceTypeFolderExtended m_resourceType; /** * Public empty constructor, required for {@link A_CmsAjaxGallery#createInstance(String, CmsJspActionElement)}.<p> */ public A_CmsAjaxGallery() { this(null); } /** * Public constructor with JSP action element.<p> * * @param jsp an initialized JSP action element */ public A_CmsAjaxGallery(CmsJspActionElement jsp) { super(jsp); // perform other initialization init(); } /** * Public constructor with JSP variables.<p> * * @param context the JSP page context * @param req the JSP request * @param res the JSP response */ public A_CmsAjaxGallery(PageContext context, HttpServletRequest req, HttpServletResponse res) { this(new CmsJspActionElement(context, req, res)); } /** * Creates a new gallery instance of the given gallery type name.<p> * * @param galleryTypeName the gallery type name to create the instance for * @param jsp an initialized JSP action element * * @return a new gallery instance of the given gallery type name */ public static A_CmsAjaxGallery createInstance(String galleryTypeName, CmsJspActionElement jsp) { if (jsp != null) { // must have a valid JSP in order to read from the user session HttpSession session = jsp.getRequest().getSession(); // lookup the workplace settings CmsWorkplaceSettings settings = (CmsWorkplaceSettings)session.getAttribute(CmsWorkplaceManager.SESSION_WORKPLACE_SETTINGS); if (settings != null) { if (CmsStringUtil.isEmpty(galleryTypeName)) { // look up the gallery type from the settings galleryTypeName = settings.getGalleryType(); } else { // store the last used gallery type name settings.setGalleryType(galleryTypeName); } } } // get the gallery class name for the type A_CmsAjaxGallery template = OpenCms.getWorkplaceManager().getGalleries().get(galleryTypeName); if (template == null) { // requested gallery type is not configured CmsMessageContainer message; if (jsp == null) { message = Messages.get().container(Messages.LOG_UNKNOWN_GALLERY_TYPE_REQ_1, galleryTypeName); } else { message = Messages.get().container( Messages.LOG_UNKNOWN_GALLERY_TYPE_REQ_JSP_2, galleryTypeName, jsp.info("opencms.request.element.uri")); } LOG.error(message.key()); throw new CmsRuntimeException(message); } try { // first get the class of the gallery Class galleryClass = Class.forName(template.getResourceType().getFolderClassName()); // create a new instance and cast to a gallery A_CmsAjaxGallery galleryInstance = (A_CmsAjaxGallery)galleryClass.newInstance(); // set the type name and id galleryInstance.m_resourceType = template.getResourceType(); galleryInstance.m_galleryTypeParams = template.getResourceType().getFolderClassParams(); // initialize the members galleryInstance.initWorkplaceMembers(jsp); // perform other initialization galleryInstance.init(); // return the result return galleryInstance; } catch (Exception e) { // requested type is not configured CmsMessageContainer message; if (jsp == null) { message = Messages.get().container( Messages.LOG_CREATE_GALLERY_INSTANCE_FAILED_2, template.getResourceType().getFolderClassName(), galleryTypeName); } else { message = Messages.get().container( Messages.LOG_CREATE_GALLERY_INSTANCE_FAILED_JSP_3, template.getResourceType().getFolderClassName(), galleryTypeName, jsp.info("opencms.request.element.uri")); } LOG.error(message.key()); throw new CmsRuntimeException(message); } } /** * Returns a list of galleries which have the required gallery type id.<p> * * @param galleryTypeId type id of the gallery * @param cms the initialized CmsObject for the current user * @return a list of galleries */ public static List<CmsResource> getGalleries(int galleryTypeId, CmsObject cms) { List<CmsResource> galleries = new ArrayList<CmsResource>(); try { // get the galleries of the current site galleries = cms.readResources("/", CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireType(galleryTypeId)); } catch (CmsException e) { // error reading resources with filter LOG.error(e.getLocalizedMessage(), e); } // if the current site is NOT the root site - add all other galleries from the system path if (!cms.getRequestContext().getSiteRoot().equals("")) { List<CmsResource> systemGalleries = null; try { // get the galleries in the /system/ folder systemGalleries = cms.readResources( CmsWorkplace.VFS_PATH_SYSTEM, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireType(galleryTypeId)); } catch (CmsException e) { // error reading resources with filter LOG.error(e.getLocalizedMessage(), e); } if ((systemGalleries != null) && (systemGalleries.size() > 0)) { // add the found system galleries to the result galleries.addAll(systemGalleries); } } // return the found galleries return galleries; } /** * Initializes the gallery dialog before redirecting.<p> * * @param wp the workplace object */ public static void initGallery(CmsDialog wp) { // 1. get "gallerytypename" by reading the folderpath String galleryTypeName = null; if (wp.useNewStyle()) { galleryTypeName = CmsResource.getName(CmsResource.getFolderPath(wp.getAdminTool().getHandler().getLink())); } else { galleryTypeName = CmsResource.getName(CmsResource.getFolderPath(wp.getJsp().getRequestContext().getUri())); } if (galleryTypeName.endsWith("/")) { galleryTypeName = galleryTypeName.substring(0, galleryTypeName.length() - 1); } if (!galleryTypeName.equals("commons")) { // 2. set in user settings wp.getSettings().setGalleryType(galleryTypeName); } } /** * Called from the JSP that is used for the AJAX requests to OpenCms.<p> */ public void displayDialog() { if (DIALOG_CHANGEITEMTITLE.equals(getParamAction())) { // build the JSON object for the current item with changed title property changeItemTitle(getJsp().getRequest().getParameter(PARAM_ITEMPATH)); } else if (DIALOG_CHANGEITEMLINKURL.equals(getParamAction())) { // build the JSON object for the current item with changed resource content (CmsResourcePointer) changeItemLinkUrl(getJsp().getRequest().getParameter(PARAM_ITEMPATH)); } else if (DIALOG_GETCATEGORIES.equals(getParamAction())) { // get the available categories as JSON array buildJsonCategoryList(); } else if (DIALOG_GETGALLERIES.equals(getParamAction())) { // get the available galleries as JSON array buildJsonGalleryList(); } else if (DIALOG_GETGALLERY.equals(getParamAction())) { // get the desired gallery as JSON object buildJsonGalleryItem(getJsp().getRequest().getParameter(PARAM_GALLERYPATH)); } else if (DIALOG_GETITEMS.equals(getParamAction())) { if (LISTMODE_CATEGORY.equals(getParamListMode())) { // get the items of selected category buildJsonResourceItems(getCategoryItems(), null); } else { // get the items of a selected gallery buildJsonResourceItems(getGalleryItems(), getParamGalleryPath()); } } else if (DIALOG_GETACTIVEITEM.equals(getParamAction())) { // build the JSON object for the currently active item buildJsonActiveItem(getJsp().getRequest().getParameter(PARAM_ITEMPATH)); } } /** * Returns a list of galleries which have the required gallery type id.<p> * * @return a list of galleries */ public List<CmsResource> getGalleries() { return getGalleries(getGalleryTypeId(), getCms()); } /** * Returns a list of gallery items (resources) for the currently selected gallery and resource type id.<p> * * @return a list of gallery items (resources) */ public List<CmsResource> getGalleryItems() { if (m_galleryItems == null) { // gallery items have not been read yet int resTypeId = getGalleryItemsTypeId(); if (CmsStringUtil.isNotEmpty(getParamGalleryPath())) { try { // set last used gallery in settings to current gallery getSettings().setLastUsedGallery(getGalleryTypeId(), getParamGalleryPath()); CmsResourceFilter filter; if (resTypeId == -1) { // filter all resources that are files filter = CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireTimerange().addRequireFile(); } else { // filter all resources of the required type filter = CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireTimerange().addRequireType( resTypeId); } m_galleryItems = getCms().readResources(getParamGalleryPath(), filter, false); } catch (CmsException e) { // error reading resources LOG.error(e.getLocalizedMessage(), e); } catch (NullPointerException e) { // ignore this exception } } } return m_galleryItems; } /** * Returns the type id of the gallery items that should be listed.<p> * * In case of downloadgallery use '-1' to list all resources excluding folders.<p> * * @return the type id of the gallery items that should be listed */ public abstract int getGalleryItemsTypeId(); /** * Returns the type id of this gallery instance.<p> * * @return the type id of this gallery instance */ public abstract int getGalleryTypeId(); /** * Returns the type name of this gallery instance.<p> * * @return the type name of this gallery instance */ public abstract String getGalleryTypeName(); /** * Returns the (optional) parameters of this gallery instance.<p> * * @return the (optional) parameters of this gallery instance */ public String getGalleryTypeParams() { return m_galleryTypeParams; } /** * Returns the current mode of the dialog.<p> * * This is necessary to distinguish between widget mode, view mode and editor mode.<p> * * @return the current mode of the dialog */ public String getParamDialogMode() { if (m_paramDialogMode == null) { return ""; } return m_paramDialogMode; } /** * Returns the input field ID when in widget mode.<p> * * @return the input field ID */ public String getParamFieldId() { return m_paramFieldId; } /** * Returns the path of the gallery to display.<p> * * @return the path of the gallery to display */ public String getParamGalleryPath() { if (CmsStringUtil.isEmpty(m_paramGalleryPath)) { m_paramGalleryPath = ""; } return m_paramGalleryPath; } /** * Returns the list mode for getting the items, either {@link #LISTMODE_CATEGORY} or {@link #LISTMODE_GALLERY}.<p> * * @return the list mode for getting the item */ public String getParamListMode() { return m_paramListMode; } /** * Returns the property value parameter.<p> * * @return the property value parameter */ public String getParamPropertyValue() { return m_paramPropertyValue; } /** * Returns the extended folder resource type this gallery is based on.<p> * * @return the extended folder resource type this gallery is based on */ public CmsResourceTypeFolderExtended getResourceType() { return m_resourceType; } /** * Initialization method that is called after the gallery instance has been created.<p> * * It can be overwritten in the inherited class, e.g. {@link org.opencms.workplace.galleries.CmsAjaxImageGallery#init()}.<p> */ public void init() { // default gallery does not require initialization } /** * Returns if the dialog mode is the "editor" mode.<p> * * @return <code>true</code> if the dialog mode is the "editor" mode, otherwise <code>false</code> */ public boolean isModeEditor() { return MODE_EDITOR.equals(getParamDialogMode()); } /** * Returns if the dialog mode is the "view" mode.<p> * * @return <code>true</code> if the dialog mode is the "view" mode, otherwise <code>false</code> */ public boolean isModeView() { return MODE_VIEW.equals(getParamDialogMode()); } /** * Returns if the dialog mode is the "widget" mode.<p> * * @return <code>true</code> if the dialog mode is the "editor" mode, otherwise <code>false</code> */ public boolean isModeWidget() { return MODE_WIDGET.equals(getParamDialogMode()); } /** * Sets the current mode of the dialog.<p> * * This is necessary to distinguish between widget mode and editor mode.<p> * * @param dialogMode the current mode of the dialog */ public void setParamDialogMode(String dialogMode) { m_paramDialogMode = dialogMode; } /** * Sets the input field ID if in widget mode.<p> * * @param fieldId the input field ID */ public void setParamFieldId(String fieldId) { m_paramFieldId = fieldId; } /** * Sets the path of the gallery to display.<p> * * @param galleryPath the path of the gallery to display */ public void setParamGalleryPath(String galleryPath) { m_paramGalleryPath = galleryPath; } /** * Sets the list mode for getting the items, either {@link #LISTMODE_CATEGORY} or {@link #LISTMODE_GALLERY}.<p> * * @param paramListMode the list mode for getting the items */ public void setParamListMode(String paramListMode) { m_paramListMode = paramListMode; } /** * Sets the property value parameter.<p> * * @param paramPropertyValue the property value parameter to set */ public void setParamPropertyValue(String paramPropertyValue) { m_paramPropertyValue = paramPropertyValue; } /** * Sets the extended folder resource type this gallery is based on.<p> * * @param type the extended folder resource type this gallery is based on */ public void setResourceType(CmsResourceTypeFolderExtended type) { m_resourceType = type; } /** * Builds the Javascript to set the currently active item object.<p> * * @param itemUrl the URL of the currently selected item */ protected void buildJsonActiveItem(String itemUrl) { if (itemUrl.startsWith(OpenCms.getSiteManager().getWorkplaceServer())) { // remove workplace server prefix itemUrl = itemUrl.substring(OpenCms.getSiteManager().getWorkplaceServer().length()); } if (itemUrl.startsWith(OpenCms.getSystemInfo().getOpenCmsContext())) { // remove context prefix to read resource from VFS itemUrl = itemUrl.substring(OpenCms.getSystemInfo().getOpenCmsContext().length()); } try { JspWriter out = getJsp().getJspContext().getOut(); if (getCms().existsResource(itemUrl)) { try { out.print(buildJsonItemObject(getCms().readResource(itemUrl))); } catch (CmsException e) { // can not happen in theory, because we used existsResource() before... } } else { out.print(RETURNVALUE_NONE); } } catch (IOException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } /** * Builds the JSON code for the category list as JSON array.<p> */ protected void buildJsonCategoryList() { CmsCategoryService catService = CmsCategoryService.getInstance(); List<CmsCategory> foundCategories = Collections.emptyList(); String editedResource = null; if (CmsStringUtil.isNotEmpty(getParamResource())) { editedResource = getParamResource(); } try { foundCategories = catService.readCategories(getCms(), "", true, editedResource); } catch (CmsException e) { // error reading categories } // the next lines sort the categories according to their path Map<String, CmsCategory> sorted = new TreeMap<String, CmsCategory>(); Iterator<CmsCategory> i = foundCategories.iterator(); while (i.hasNext()) { CmsCategory category = i.next(); String categoryPath = category.getPath(); if (sorted.get(categoryPath) != null) { continue; } sorted.put(categoryPath, category); } foundCategories = new ArrayList<CmsCategory>(sorted.values()); JSONArray categories = new JSONArray(); i = foundCategories.iterator(); while (i.hasNext()) { CmsCategory cat = i.next(); JSONObject jsonObj = new JSONObject(); try { // 1: category title jsonObj.put("title", cat.getTitle()); // 2: category path jsonObj.put("path", cat.getPath()); // 3: category root path jsonObj.put("rootpath", cat.getRootPath()); // 4 category level jsonObj.put("level", CmsResource.getPathLevel(cat.getPath())); // 4: active flag jsonObj.put("active", false); categories.put(jsonObj); } catch (JSONException e) { // TODO: error handling } } JspWriter out = getJsp().getJspContext().getOut(); try { out.print(categories.toString()); } catch (IOException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } /** * Creates a JSON object with the information found on the given gallery URL.<p> * * @param galleryUrl the given gallery URL */ protected void buildJsonGalleryItem(String galleryUrl) { try { JspWriter out = getJsp().getJspContext().getOut(); if (getCms().existsResource(galleryUrl)) { JSONObject jsonObj = new JSONObject(); try { CmsResource res = getCms().readResource(galleryUrl); String path = getCms().getSitePath(res); // read the gallery title String title = getCms().readPropertyObject(res, CmsPropertyDefinition.PROPERTY_TITLE, false).getValue( ""); try { // 1: gallery title jsonObj.put("title", title); // 2: gallery path jsonObj.put("path", path); // 3: active flag jsonObj.put("active", true); out.print(jsonObj); } catch (JSONException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } catch (CmsException e) { // error reading title property if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } else { out.print(RETURNVALUE_NONE); } } catch (IOException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } /** * Builds the JSON code for the gallery list as JSON array.<p> */ protected void buildJsonGalleryList() { String lastUsed = getSettings().getLastUsedGallery(getGalleryTypeId()); // check the value of last Used, if gallery is opened for the first time if (CmsStringUtil.isEmpty(lastUsed)) { // start gallery settings for this gallery type for the current user String startGallerySetting = getSettings().getUserSettings().getStartGallery(getGalleryTypeName(), getCms()); if (startGallerySetting != null) { // handle the case, "global settings" are selected if (startGallerySetting.equals(CmsPreferences.INPUT_DEFAULT)) { // get selected value from workplace xml settings String preselectedValue = OpenCms.getWorkplaceManager().getDefaultUserSettings().getStartGallery( getGalleryTypeName()); if (preselectedValue != null) { startGallerySetting = preselectedValue; } } // checks if the resource exists String sitePath = getCms().getRequestContext().removeSiteRoot(startGallerySetting); if (getCms().existsResource(sitePath)) { lastUsed = sitePath; } } } JSONArray galleries = new JSONArray(); Iterator<CmsResource> i = getGalleries().iterator(); boolean isFirst = true; while (i.hasNext()) { CmsResource res = i.next(); String path = getCms().getSitePath(res); JSONObject jsonObj = new JSONObject(); // 1: gallery title String title = ""; try { // read the gallery title title = getCms().readPropertyObject(path, CmsPropertyDefinition.PROPERTY_TITLE, false).getValue(""); } catch (CmsException e) { // error reading title property if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } try { jsonObj.put("title", title); // 2: gallery path jsonObj.put("path", path); // 3: active flag boolean active = false; if ((CmsStringUtil.isEmpty(lastUsed) && isFirst) || path.equals(lastUsed)) { // TODO: adjust logic to get active gallery active = true; } jsonObj.put("active", active); galleries.put(jsonObj); } catch (JSONException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } isFirst = false; } JspWriter out = getJsp().getJspContext().getOut(); try { out.print(galleries.toString()); } catch (IOException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } /** * Fills the JSON object with the information used for all resource types.<p> * * <ul> * <li><code>sitepath</code>: site path to the resource.</li> * <li><code>linkpath</code>: substituted url of the resource.</li> * <li><code>title</code>: title property of the resource.</li> * <li><code>size</code>: size of the resource in kb.</li> * <li><code>datecreated</code>: the creation date of the resource.</li> * <li><code>datelastmodified</code>: the modification date.</li> * <li><code>state</code>: the state of the resource, new or changed.</li> * <li><code>lockedby</code>: indicates if the resource is locked by another user.</li> * <li><code>editable</code>: editable flag to determine if item is editable and can be lockes by the user.</li> * <li><code>writepermission</code>: flag to indicate if the user has write permissions for given resource.</li> * <li><code>directpublish</code>: flag to indicate if the user has write direct publish permission for given resource.</li> * <li><code>description</code>: description property of the resource.</li> * </ul> * * @param jsonObj containing information used by all possible resource * @param res the resource to create the object from * @param sitePath site path to the object */ protected void buildJsonItemCommonPart(JSONObject jsonObj, CmsResource res, String sitePath) { try { // 1: file item site path jsonObj.put("sitepath", sitePath); // 2: substituted file item url jsonObj.put("linkpath", getJsp().link(sitePath)); // 3: file item title jsonObj.put("title", CmsStringUtil.escapeJavaScript(getJsp().property( CmsPropertyDefinition.PROPERTY_TITLE, sitePath, res.getName()))); // 4: file size (in kb) jsonObj.put("size", (res.getLength() / 1024) + " " + key(org.opencms.workplace.galleries.Messages.GUI_LABEL_KILOBYTES_0)); // 5: file creation date (formatted) jsonObj.put("datecreated", getMessages().getDateTime(res.getDateCreated())); // 6: file modification date (formatted) jsonObj.put("datelastmodified", getMessages().getDateTime(res.getDateLastModified())); // 7: file state, if the item is new or changed CmsResourceState state = res.getState(); CmsLock lock = CmsLock.getNullLock(); try { // obtain current lock state to determine correct resource state and editable flag lock = getCms().getLock(res); } catch (CmsException e) { // ignore, lock state could not be determined } if (!lock.isNullLock() && lock.getType().isPublish()) { state = CmsResourceState.STATE_UNCHANGED; } jsonObj.put("state", state); // 8: determine if the item is locked by another user String locked = ""; if (!lock.isNullLock() && !lock.getType().isPublish() && !lock.getUserId().equals(getCms().getRequestContext().getCurrentUser().getId())) { try { locked = getCms().readUser(lock.getUserId()).getName(); } catch (CmsException e) { // failed to read user, use ID as user name locked = lock.getUserId().toString(); } } jsonObj.put("lockedby", locked); // 9: item editable flag to determine if item is editable (offline project and can be locked by the current user) boolean editable = false; // 10: item write permissions to determine if the user has write permission boolean writePermission = false; // 10: item direct publish flag to determine if the user has direct publish permission boolean directPublishPermission = false; try { // test if the resource is in the offline project and it can be locked by the user if (!getCms().getRequestContext().getCurrentProject().isOnlineProject() && lock.isLockableBy(getCms().getRequestContext().getCurrentUser())) { editable = true; // test if the user has the write permission if (getCms().hasPermissions(res, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.ALL)) { writePermission = true; } // test if the user has direct publish permission if (getCms().hasPermissions( res, CmsPermissionSet.ACCESS_DIRECT_PUBLISH, false, CmsResourceFilter.ALL)) { directPublishPermission = true; } } } catch (CmsException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } jsonObj.put("editable", editable); jsonObj.put("writepermission", writePermission); jsonObj.put("directpublish", directPublishPermission); // 11: item description String desc = getJsp().property(CmsPropertyDefinition.PROPERTY_DESCRIPTION, sitePath, ""); jsonObj.put("description", CmsStringUtil.escapeJavaScript(desc)); } catch (JSONException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } /** * Returns a JSON object containing information of the given resource for usage in the gallery.<p> * * The content of the JSON object consists of a common and a specific part of the given resource.<p> * * @param res the resource to create the object from * @return the JSON object containing information from the given resource */ protected JSONObject buildJsonItemObject(CmsResource res) { // create a new JSON object JSONObject jsonObj = new JSONObject(); String sitePath = getCms().getRequestContext().getSitePath(res); OpenCms.getSystemInfo().getOpenCmsContext(); // fill JSON object with common information buildJsonItemCommonPart(jsonObj, res, sitePath); // fill JSON object with specific information buildJsonItemSpecificPart(jsonObj, res, sitePath); return jsonObj; } /** * Fills the JSON object with the specific information used for this resource type.<p> * * @param jsonObj containing information used by all possible resource * @param res the resource to create the object from * @param sitePath site path to the object */ protected abstract void buildJsonItemSpecificPart(JSONObject jsonObj, CmsResource res, String sitePath); /** * Builds the JSON code to create items for the folder.<p> * * @param resourceitems the file resource to build the displayed items * @param parentFolder the parent folder of the collected files (for a gallery) */ protected void buildJsonResourceItems(List<CmsResource> resourceitems, String parentFolder) { if (resourceitems == null) { resourceitems = new ArrayList<CmsResource>(); } boolean isPublishEnabled = false; boolean hasDirectPublish = false; boolean hasWritePermission = false; if (CmsStringUtil.isNotEmpty(parentFolder)) { // check if there are changes in the currently selected gallery and the user has direct edit permissions try { if ((OpenCms.getPublishManager().getPublishList(getCms(), getCms().readResource(parentFolder), false).size() > 0)) { isPublishEnabled = true; } } catch (CmsException e) { // ignore, gallery can not be published } // check if the user has direst publish permissions, // used to enable the gallerypublish button, if user has enough permissions try { if (getCms().hasPermissions( getCms().readResource(parentFolder), CmsPermissionSet.ACCESS_DIRECT_PUBLISH, false, CmsResourceFilter.ALL)) { hasDirectPublish = true; } } catch (CmsException e) { // ignore, no publish permissions for gallery } try { // check if the user has write permissions, // used to display the upload buttons if (getCms().hasPermissions( getCms().readResource(parentFolder), CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.ALL)) { hasWritePermission = true; } } catch (CmsException e) { // ignore, no write permissions for gallery } } JSONObject publishInfo = new JSONObject(); try { publishInfo.put("publishable", isPublishEnabled); publishInfo.put("directpublish", hasDirectPublish); publishInfo.put("writepermission", hasWritePermission); } catch (JSONException e) { // ignore } JSONArray items = new JSONArray(); items.put(publishInfo); Iterator<CmsResource> i = resourceitems.iterator(); while (i.hasNext()) { CmsResource res = i.next(); // build a JSON object from the item and add it to the list items.put(buildJsonItemObject(res)); } JspWriter out = getJsp().getJspContext().getOut(); try { // print the JSON array out.print(items.toString()); } catch (IOException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } /** * Changes the content of the CmsResource.<p> * This function should be overwritten in {@link org.opencms.workplace.galleries.CmsAjaxLinkGallery}.<p> * * @param itemUrl the item URL * */ protected void changeItemLinkUrl(String itemUrl) { // the most galleries do not provide this method } /** * Changes the title property value of the given item.<p> * * @param itemUrl the item URL on which the title is changed */ protected void changeItemTitle(String itemUrl) { try { JspWriter out = getJsp().getJspContext().getOut(); if (getCms().existsResource(itemUrl)) { try { writeTitleProperty(getCms().readResource(itemUrl)); out.print(buildJsonItemObject(getCms().readResource(itemUrl))); } catch (CmsException e) { // can not happen in theory, because we used existsResource() before... } } else { out.print(RETURNVALUE_NONE); } } catch (IOException e) { if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } /** * Returns the resource items for the selected category.<p> * * @return the resource items for the selected category */ protected List<CmsResource> getCategoryItems() { List<CmsResource> result = Collections.emptyList(); if (CmsStringUtil.isNotEmpty(getParamGalleryPath())) { try { CmsCategoryService service = CmsCategoryService.getInstance(); // get the edited resource if present String editedResource = "/"; if (CmsStringUtil.isNotEmpty(getParamResource())) { editedResource = CmsResource.getFolderPath(getParamResource()); } // read the matching resources for the category result = service.readCategoryResources(getCms(), getParamGalleryPath(), true, editedResource); // filter the matched resources to get only the specific items as result int resTypeId = getGalleryItemsTypeId(); if (resTypeId != -1) { List<CmsResource> unfiltered = new ArrayList<CmsResource>(result); result = new ArrayList<CmsResource>(unfiltered.size()); Iterator<CmsResource> i = unfiltered.iterator(); while (i.hasNext()) { CmsResource res = i.next(); if (res.getTypeId() == resTypeId) { result.add(res); } } } } catch (CmsException e) { // error reading resources if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } catch (NullPointerException e) { // ignore this exception if (LOG.isErrorEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } return result; } /** * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) */ @Override protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { // fill the parameter values in the get/set methods fillParamValues(request); // set the dialog type setParamDialogtype(LISTMODE_GALLERY); if (CmsStringUtil.isEmpty(getParamGalleryPath())) { String lastUsedGallery = getSettings().getLastUsedGallery(getGalleryTypeId()); if (CmsStringUtil.isNotEmpty(lastUsedGallery)) { // set the resourcepath of the last used gallery if the resource is not deleted try { getCms().readResource(lastUsedGallery, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); setParamGalleryPath(lastUsedGallery); } catch (CmsException e) { // reading the last used gallery failed, may be deleted } } } } /** * Changes the value of the property title for the specified resource.<p> * * @param res the resource to change the property value */ protected void writeTitleProperty(CmsResource res) { String resPath = getCms().getSitePath(res); String currentPropertyValue = getParamPropertyValue(); try { CmsProperty currentProperty = getCms().readPropertyObject( resPath, CmsPropertyDefinition.PROPERTY_TITLE, false); // detect if property is a null property or not if (currentProperty.isNullProperty()) { // create new property object and set key and value currentProperty = new CmsProperty(); currentProperty.setName(CmsPropertyDefinition.PROPERTY_TITLE); if (OpenCms.getWorkplaceManager().isDefaultPropertiesOnStructure()) { // set structure value currentProperty.setStructureValue(currentPropertyValue); currentProperty.setResourceValue(null); } else { // set resource value currentProperty.setStructureValue(null); currentProperty.setResourceValue(currentPropertyValue); } } else if (currentProperty.getStructureValue() != null) { // structure value has to be updated currentProperty.setStructureValue(currentPropertyValue); currentProperty.setResourceValue(null); } else { // resource value has to be updated currentProperty.setStructureValue(null); currentProperty.setResourceValue(currentPropertyValue); } CmsLock lock = getCms().getLock(res); if (lock.isUnlocked()) { // lock resource before operation getCms().lockResource(resPath); } // write the property to the resource getCms().writePropertyObject(resPath, currentProperty); // unlock the resource getCms().unlockResource(resPath); } catch (CmsException e) { // writing the property failed, log error LOG.error(e.getLocalizedMessage(), e); } } }