/*
* File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.documentcenter/src/com/alkacon/opencms/documentcenter/CmsDocumentFrontend.java,v $
* Date : $Date: 2010/03/19 15:31:13 $
* Version: $Revision: 1.3 $
*
* This file is part of the Alkacon OpenCms Add-On Module Package
*
* Copyright (c) 2010 Alkacon Software GmbH (http://www.alkacon.com)
*
* The Alkacon OpenCms Add-On Module Package is free software:
* you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alkacon OpenCms Add-On Module Package 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the Alkacon OpenCms Add-On Module Package.
* If not, see http://www.gnu.org/licenses/.
*
* For further information about Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com.
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org.
*/
package com.alkacon.opencms.v8.documentcenter;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.i18n.CmsMessages;
import org.opencms.jsp.CmsJspActionElement;
import org.opencms.jsp.CmsJspNavElement;
import org.opencms.util.CmsStringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
/**
* Provides customized methods for the document center frontend output.<p>
*
* @author Andreas Zahner
*
* @version $Revision: 1.3 $
*
* @since 6.2.1
*/
/**
*
*/
public class CmsDocumentFrontend extends CmsJspActionElement {
/** Request attribute that stores if a disclaimer should be shown. */
public static final String ATTR_DISCLAIMER = "oamp_doccenter_disclaimer";
/** Request attribute that stores the absolute path to the current document center folder. */
public static final String ATTR_FULLPATH = "oamp_doccenter_fullpath";
/** Request attribute that stores the relative path to the current document center folder. */
public static final String ATTR_PATHPART = "oamp_doccenter_pathpart";
/** Request attribute that stores the absolute path to the document center start folder. */
public static final String ATTR_STARTPATH = "oamp_doccenter_startpath";
/** Name of the column: date created. */
public static final String COLUMN_NAME_DATECREATED = "datecreated";
/** Name of the column: date modified. */
public static final String COLUMN_NAME_DATEMODIFIED = "datemodified";
/** Name of the column: document folder. */
public static final String COLUMN_NAME_FOLDER = "folder";
/** Name of the column: document id. */
public static final String COLUMN_NAME_ID = "id";
/** Name of the column: document languages. */
public static final String COLUMN_NAME_LANGUAGE = "lang";
/** Name of the column: document size. */
public static final String COLUMN_NAME_SIZE = "size";
/** Name of the column: document title. */
public static final String COLUMN_NAME_TITLE = "title";
/** Name of the column: document type. */
public static final String COLUMN_NAME_TYPE = "type";
/** The sortable column default sort directions, must correspond to the sortable columns {@link #COLUMNS_SORTABLE}. */
public static final String[] COLUMNS_DIRECTIONS = {
CmsDocument.SORT_DIRECTION_ASC,
CmsDocument.SORT_DIRECTION_ASC,
CmsDocument.SORT_DIRECTION_ASC,
CmsDocument.SORT_DIRECTION_DESC,
CmsDocument.SORT_DIRECTION_DESC,
CmsDocument.SORT_DIRECTION_DESC};
/** The sortable column default sort directions as list. */
public static final List<String> COLUMNS_DIRECTIONS_LIST = Arrays.asList(COLUMNS_DIRECTIONS);
/** Stores the column names that are sortable. */
public static final String[] COLUMNS_SORTABLE = {
COLUMN_NAME_TYPE,
COLUMN_NAME_ID,
COLUMN_NAME_TITLE,
COLUMN_NAME_SIZE,
COLUMN_NAME_DATEMODIFIED,
COLUMN_NAME_DATECREATED};
/** The column names that are sortable as list. */
public static final List<String> COLUMNS_SORTABLE_LIST = Arrays.asList(COLUMNS_SORTABLE);
/** Name of the file extensions of the icons of the document list. */
public static final String ICON_POSTFIX = ".gif";
/** Page type: default (shows the document list). */
public static final String PAGE_TYPE_DEFAULT = "default";
/** Request parameter name for the sort column parameter. */
public static final String PARAM_SORT_COLUMN = "sortcol";
/** Request parameter name for the sort direction parameter. */
public static final String PARAM_SORT_DIRECTION = "sortdir";
/** Property name to look if the document id column is shown. */
public static final String PROPERTY_COLUMN_ID = "docs.columnid";
/** Property name to look for document list column names to hide. */
public static final String PROPERTY_COLUMNS_HIDE = "docs.hidecolumns";
/** Property name to look for document list date columns to hide (old way, used for compatibility reasons). */
public static final String PROPERTY_COLUMNS_HIDE_DATE = "categoryDateCreated";
/** Property name to determine if the document center should consider attachments of the documents. */
public static final String PROPERTY_USE_ATTACHMENTS = "docs.useattachments";
/** Property name to set the default type if using different types. */
public static final String PROPERTY_USE_DEFAULTTYPE = "docs.defaulttype";
/** Property name to determine if the document center should consider language versions of the documents. */
public static final String PROPERTY_USE_LANGUAGES = "docs.uselanguages";
/** Property name to determine if the document center should consider different types of the documents. */
public static final String PROPERTY_USE_TYPES = "docs.usetypes";
/** The property values of the sort methods, must be in the same order as {@link #COLUMNS_SORTABLE}. */
public static final String[] SORT_METHODS = {
CmsDocument.SORT_METHOD_TYPE,
CmsDocument.SORT_METHOD_BY_ID,
CmsDocument.SORT_METHOD_ALPHABETICAL,
CmsDocument.SORT_METHOD_SIZE,
CmsDocument.SORT_METHOD_BY_DATEMODIFIED,
CmsDocument.SORT_METHOD_BY_DATECREATED};
/** The property values of the sort methods as list. */
public static final List<String> SORT_METHODS_LIST = Arrays.asList(SORT_METHODS);
/** The extension of the default type if using different types of documents. */
private String m_defaultType;
/** The page type to show. */
private String m_pageType;
/** The parameter of the sort column. */
private String m_paramSortColumn;
/** The parameter of the sort direction. */
private String m_paramSortDirection;
/** The value of the sort method property ("method:direction:includefolders"). */
private String m_sortMethod;
/** Determines if attachments of documents are present. */
private Boolean m_useAttachments;
/** Determines if language versions of documents are present. */
private Boolean m_useLanguages;
/** Determines if different types of documents are present. */
private Boolean m_useTypes;
/**
* Empty constructor, required for every JavaBean.
*/
public CmsDocumentFrontend() {
super();
}
/**
* Constructor, with parameters.
*
* @param context the JSP page context object
* @param req the JSP request
* @param res the JSP response
*/
public CmsDocumentFrontend(PageContext context, HttpServletRequest req, HttpServletResponse res) {
super(context, req, res);
// TODO: fix all current uri references to use proper sitepath
}
/**
* Creates the HTML code for the default breadcrumb navigation without the "up one folder" icon.<p>
*
* Used by: elements/navigation.jsp.<p>
*
* @param startFolder the start folder to build the navigation from
* @param navList the navigation elements (CmsJspNavElement)
* @param anchorClass the CSS class which will be used for the anchors
* @param separator the separator which will be used to separate the entries
* @param sepBeforeFirst if true, separator will be displayed before first element, too
* @return the HTML code for the breadcrumb navigation
*/
public String buildBreadCrumbNavigation(
String startFolder,
List<CmsJspNavElement> navList,
String anchorClass,
String separator,
boolean sepBeforeFirst) {
StringBuffer result = new StringBuffer(64);
boolean isFirst = true;
if (sepBeforeFirst) {
isFirst = false;
}
String locNavText = CmsPropertyDefinition.PROPERTY_NAVTEXT + "_" + getRequestContext().getLocale().toString();
String locTitle = CmsPropertyDefinition.PROPERTY_TITLE + "_" + getRequestContext().getLocale().toString();
String currFolder = (String)getRequest().getAttribute(ATTR_FULLPATH);
// create the navigation
Iterator<CmsJspNavElement> i = navList.iterator();
while (i.hasNext()) {
CmsJspNavElement navElement = i.next();
String navText = navElement.getProperties().get(locNavText);
if (CmsStringUtil.isEmptyOrWhitespaceOnly(navText)) {
navText = navElement.getNavText();
}
if (navElement.getResourceName().startsWith(startFolder)) {
// check the navigation text
if (navText.indexOf("??? NavText") != -1) {
navText = navElement.getProperties().get(locTitle);
if (CmsStringUtil.isEmptyOrWhitespaceOnly(navText)) {
navText = navElement.getTitle();
}
if (CmsStringUtil.isEmptyOrWhitespaceOnly(navText)) {
navText = navElement.getFileName();
}
if (navText.endsWith("/")) {
navText = navText.substring(0, (navText.length() - 1));
}
}
// don't show separator in front of first element
if (!isFirst) {
result.append(separator);
} else {
isFirst = false;
}
if (navElement.getResourceName().equals(currFolder) && (navList.size() > 1)) {
// the current folder will not be linked
result.append("<span class=\"");
result.append(anchorClass);
result.append("\">");
result.append(navText);
result.append("</span>");
} else {
// create the link to the folder
result.append("<a href=\"");
result.append(CmsDocumentFactory.getLink(this, navElement.getResourceName()));
result.append("\" class=\"");
result.append(anchorClass);
result.append("\">");
result.append(navText);
result.append("</a>");
}
}
}
return result.toString();
}
/**
* Creates the HTML code for the document or resource icon in document list, version list and search result list.<p>
*
* Used by: jsptemplates/list_documents.txt, elements/docversions.jsp, pages/jsp_pages/page_search_code.jsp.<p>
*
* @param docName the resource name of the document
* @param messages the localized messages
* @param resourcePath the path to the images
* @param isFolder true if the document is a folder, otherwise false
* @return the HTML code for the document icon
*/
public String buildDocIcon(String docName, CmsMessages messages, String resourcePath, boolean isFolder) {
return buildDocIcon(docName, messages, resourcePath, isFolder, 16, 16);
}
/**
* Creates the HTML code for the document or resource icon in document list, version list and search result list.<p>
*
* Used by: jsptemplates/list_documents.txt, elements/docversions.jsp, pages/jsp_pages/page_search_code.jsp.<p>
*
* @param docName the resource name of the document
* @param messages the localized messages
* @param resourcePath the path to the images
* @param isFolder true if the document is a folder, otherwise false
* @param imgWidth the width of the icon image
* @param imgHeight the height of the icon image
* @return the HTML code for the document icon
*/
public String buildDocIcon(
String docName,
CmsMessages messages,
String resourcePath,
boolean isFolder,
int imgWidth,
int imgHeight) {
String iconSrc, iconTitle, iconAlt;
// folder
if (isFolder) {
iconSrc = "ic_folder";
iconTitle = messages.key("documentlist.icon.folder.title");
iconAlt = messages.key("documentlist.icon.folder.alt");
}
// file
else {
String postfix = CmsDocument.getPostfix(docName);
iconSrc = "ic_app_" + postfix;
iconTitle = messages.keyDefault("documentlist.icon.file.title." + postfix, "");
iconAlt = messages.keyDefault("documentlist.icon.file.alt." + postfix, "");
if ((postfix.equals("")) || (!getCmsObject().existsResource(resourcePath + iconSrc + ICON_POSTFIX))) {
iconSrc = "ic_app_unknown";
iconTitle = messages.key("documentlist.icon.file.title.unknown");
iconAlt = messages.key("documentlist.icon.file.alt.unknown");
}
}
StringBuffer result = new StringBuffer(256);
result.append("<img src=\"");
result.append(link(resourcePath + iconSrc + ICON_POSTFIX));
result.append("\" width=\"").append(imgWidth).append("\" height=\"").append(imgHeight);
result.append("\" border=\"0\" alt=\"");
result.append(iconAlt);
result.append("\" title=\"");
result.append(iconTitle);
result.append("\"/>");
return result.toString();
}
/**
* Returns the column header including the link to sort the list by the column criteria.<p>
*
* @param columnName the internal column name
* @param resourcePath the path to the image resources
* @param messages the initialized localized messages to use
* @return the column header including the link to sort the list by the column criteria
*/
public String getColumnHeader(String columnName, String resourcePath, CmsMessages messages) {
if (!isBeanSortInitialized()) {
initSort();
}
if (m_pageType.equals("default") && COLUMNS_SORTABLE_LIST.contains(columnName)) {
// column is sortable and we are on a default page, so columns are sortable
StringBuffer result = new StringBuffer(256);
String dir = m_paramSortDirection;
String newDir = dir;
boolean isCurrentColumn = false;
if (columnName.equals(m_paramSortColumn)) {
// the column is the current sort column
isCurrentColumn = true;
// switch new sort direction link for current sort column
if ((dir != null) && dir.equals(CmsDocument.SORT_DIRECTION_ASC)) {
newDir = CmsDocument.SORT_DIRECTION_DESC;
} else {
newDir = CmsDocument.SORT_DIRECTION_ASC;
}
} else {
// use default sort direction for other columns
newDir = COLUMNS_DIRECTIONS_LIST.get(COLUMNS_SORTABLE_LIST.indexOf(columnName));
}
// create the link for sorting the column
StringBuffer link = new StringBuffer(128);
link.append((String)getRequest().getAttribute(ATTR_FULLPATH));
link.append("?").append(PARAM_SORT_COLUMN).append("=").append(columnName);
link.append("&").append(PARAM_SORT_DIRECTION).append("=").append(newDir);
// set the title for the headline
String sortTitle = messages.key(
"documentlist.sort." + newDir,
messages.key("documentlist.headline." + columnName));
result.append("<a href=\"");
result.append(CmsDocumentFactory.getLink(this, link.toString()));
result.append("\" class=\"docshead\" title=\"");
result.append(sortTitle);
result.append("\">");
result.append(messages.key("documentlist.headline." + columnName));
if (isCurrentColumn) {
// set the marker icon for the current sort column
result.append(" ");
result.append("<img src=\"");
result.append(resourcePath).append("ic_sort_").append(dir).append(".png");
result.append("\" border=\"0\" alt=\"");
result.append(sortTitle);
result.append("\" title=\"");
result.append(sortTitle);
result.append("\"/>");
}
result.append("</a>");
return result.toString();
} else {
// column is not sortable, simply print localized headline
return messages.key("documentlist.headline." + columnName);
}
}
/**
* Returns the defaultType.<p>
*
* @return the defaultType
*/
public String getDefaultType() {
return m_defaultType;
}
/**
* Collects the names of the columns to hide in the document list view.<p>
*
* Columns that can be hidden are: date created, date last modified, document id.<p>
*
* @return the names of the clumns to hide
*/
public List<String> getHiddenColumns() {
List<String> result = new ArrayList<String>(4);
String ignoredCols = property(PROPERTY_COLUMNS_HIDE, "search", "");
result = CmsStringUtil.splitAsList(ignoredCols, ';');
// backward compatibility: check for property defining visibility of date columns
String showDateData = property("categoryDateCreated", "search", "");
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(showDateData)) {
List<String> showDateList = CmsStringUtil.splitAsList(showDateData, ";");
if (showDateList.size() >= 2) {
if (!Boolean.valueOf(showDateList.get(1)).booleanValue()) {
result.add(COLUMN_NAME_DATEMODIFIED);
}
}
if (showDateList.size() >= 1) {
if (!Boolean.valueOf(showDateList.get(0)).booleanValue()) {
result.add(COLUMN_NAME_DATECREATED);
}
}
}
// manually add ID column to list of hidden columns if not explicitly set to visible
String idCol = property(PROPERTY_COLUMN_ID, "search", Boolean.FALSE.toString());
boolean showIdColumn = Boolean.valueOf(idCol).booleanValue();
if (!showIdColumn) {
result.add(COLUMN_NAME_ID);
}
// check if language versions are considered
if (!isUseLanguages()) {
result.add(COLUMN_NAME_LANGUAGE);
}
return result;
}
/**
* Returns the sort method property value to use to sort the document list.<p>
*
* @return the sort method property value to use to sort the document list
*/
public String getSortMethod() {
if (!isBeanSortInitialized()) {
initSort();
}
return m_sortMethod;
}
/**
* @see org.opencms.jsp.CmsJspBean#init(javax.servlet.jsp.PageContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void init(PageContext context, HttpServletRequest req, HttpServletResponse res) {
// call super initialization
super.init(context, req, res);
// check if document language versions should be considered, the default is false
String useLanguages = property(PROPERTY_USE_LANGUAGES, "search", "false");
setUseLanguages(Boolean.valueOf(useLanguages).booleanValue());
// check if document attachments should be considered, the default is true
String useAttachments = property(PROPERTY_USE_ATTACHMENTS, "search", "true");
setUseAttachments(Boolean.valueOf(useAttachments).booleanValue());
// check if different types of documents should be considered, the default is false
String useTypes = property(PROPERTY_USE_TYPES, "search", "false");
setUseTypes(Boolean.valueOf(useTypes).booleanValue());
// get the extension for the default type if document allows different types of documents, the default is null
String defaultType = property(PROPERTY_USE_DEFAULTTYPE, "search");
setDefaultType(defaultType);
}
/**
* Initializes the necessary members to determine the sort method of the document list.<p>
*/
public void initSort() {
// read the sort parameters from the request
m_paramSortColumn = CmsStringUtil.escapeHtml(getRequest().getParameter(PARAM_SORT_COLUMN));
m_paramSortDirection = CmsStringUtil.escapeHtml(getRequest().getParameter(PARAM_SORT_DIRECTION));
// check the page type and store it
m_pageType = CmsStringUtil.escapeHtml(getRequest().getParameter("page_type"));
if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_pageType)) {
m_pageType = property("page_type", "uri", PAGE_TYPE_DEFAULT);
}
if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_paramSortColumn)) {
// no request parameters found, determine current sort method from property
String defaultSortMethod = CmsDocument.SORT_METHOD_ALPHABETICAL;
String idCol = property(PROPERTY_COLUMN_ID, "search", Boolean.FALSE.toString());
if (Boolean.valueOf(idCol).booleanValue()) {
defaultSortMethod = CmsDocument.SORT_METHOD_BY_ID;
}
m_sortMethod = property(CmsDocument.PROPERTY_SORTMETHOD, "search", defaultSortMethod);
String sortMethod = m_sortMethod;
if (sortMethod.toLowerCase().indexOf(CmsDocument.VALUE_INCLUDE_FOLDERS) != -1) {
// remove "includefolders" suffix
sortMethod = sortMethod.substring(0, sortMethod.lastIndexOf(":"));
}
if (sortMethod.indexOf(":") != -1) {
// store direction and remove it from String
m_paramSortDirection = sortMethod.substring(sortMethod.indexOf(":") + 1);
sortMethod = sortMethod.substring(0, sortMethod.indexOf(":"));
}
// determine the sort column
int listIndex = SORT_METHODS_LIST.indexOf(sortMethod.toLowerCase());
if (listIndex > -1) {
// only get column if method was found in list of sortable columns (NOT for method "by sort order")
m_paramSortColumn = COLUMNS_SORTABLE_LIST.get(listIndex);
if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_paramSortDirection)) {
// no sort direction explicitly defined, get default sort direction
m_paramSortDirection = COLUMNS_DIRECTIONS_LIST.get(listIndex);
}
}
} else {
// found request parameters
int listIndex = COLUMNS_SORTABLE_LIST.indexOf(m_paramSortColumn);
m_sortMethod = SORT_METHODS_LIST.get(listIndex) + ":" + m_paramSortDirection;
}
}
/**
* Returns if the necessary members to determine the sort method of the document list are initialized.<p>
*
* @return true if the necessary members to determine the sort method of the document list are initialized
*/
public boolean isBeanSortInitialized() {
return m_sortMethod != null;
}
/**
* Returns if the document center should consider attachments of the documents.<p>
*
* @return true if the document center should consider attachments of the documents, otherwise false
*/
public boolean isUseAttachments() {
return m_useAttachments.booleanValue();
}
/**
* Returns if the document center should consider language versions of the documents.<p>
*
* @return true if the document center should consider language versions of the documents, otherwise false
*/
public boolean isUseLanguages() {
return m_useLanguages.booleanValue();
}
/**
* Returns if the document center should consider different types of the documents.<p>
*
* @return true if the document center should consider different types of the documents, otherwise false
*/
public boolean isUseTypes() {
return m_useTypes.booleanValue();
}
/**
* Returns all properties of the document center file structure.<p>
*
* This overrides the standard property mechanism to be able to get property values
* conveniently from the document center folders and files.<p>
*
* @see org.opencms.jsp.CmsJspActionElement#properties(java.lang.String)
*/
@Override
public Map<String, String> properties(String file) {
String origUri = getRequestContext().getUri();
try {
getRequestContext().setUri((String)getRequest().getAttribute(CmsDocumentFrontend.ATTR_FULLPATH));
return super.properties(file);
} finally {
getRequestContext().setUri(origUri);
}
}
/**
* Returns a selected file property value from the document center file structure.<p>
*
* This overrides the standard property mechanism to be able to get property values
* conveniently from the document center folders and files.<p>
*
* @see org.opencms.jsp.CmsJspActionElement#property(java.lang.String, java.lang.String, java.lang.String, boolean)
*/
@Override
public String property(String name, String file, String defaultValue, boolean escapeHtml) {
String origUri = getRequestContext().getUri();
try {
getRequestContext().setUri((String)getRequest().getAttribute(CmsDocumentFrontend.ATTR_FULLPATH));
return super.property(name, file, defaultValue, escapeHtml);
} finally {
getRequestContext().setUri(origUri);
}
}
/**
* Sets the defaultType.<p>
*
* @param defaultType the defaultType to set
*/
public void setDefaultType(String defaultType) {
m_defaultType = defaultType;
}
/**
* Sets if the document center should consider attachments of the documents.<p>
*
* @param useAttachments if the document center should consider attachments of the documents
*/
public void setUseAttachments(boolean useAttachments) {
m_useAttachments = Boolean.valueOf(useAttachments);
}
/**
* Sets if the document center should consider language versions of the documents.<p>
*
* @param useLanguages if the document center should consider language versions of the documents
*/
public void setUseLanguages(boolean useLanguages) {
m_useLanguages = Boolean.valueOf(useLanguages);
}
/**
* Sets if the document center should consider different types of the documents.<p>
*
* @param useTypes if the document center should consider different types of the documents
*/
public void setUseTypes(boolean useTypes) {
m_useTypes = Boolean.valueOf(useTypes);
}
}