/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* 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.
*
* 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 com.arsdigita.cms.ui;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Resettable;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.event.TreeExpansionEvent;
import com.arsdigita.bebop.event.TreeExpansionListener;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.parameters.LongParameter;
import com.arsdigita.cms.CMS;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.Folder;
import com.arsdigita.cms.ui.folder.FolderRequestLocal;
import com.arsdigita.cms.ui.folder.FolderSelectionModel;
import com.arsdigita.cms.ui.folder.FolderTreeModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ui.LayoutPanel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.arsdigita.cms.CMSConfig;
import org.libreccm.categorization.Category;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.CmsConstants;
import org.librecms.contentsection.ContentSectionRepository;
import java.util.List;
/**
* A pane that contains a folder tree on the left and a folder manipulator on
* the right.
*
* @author David LutterKort <dlutter@redhat.com>
* @author Jens Pelzetter
*/
public class ItemSearchBrowsePane extends SimpleContainer implements Resettable,
TreeExpansionListener,
ChangeListener,
FormProcessListener,
FormSubmissionListener {
private static final String CONTENT_TYPE_ID = "ct";
private static final Logger LOGGER = LogManager.getLogger(
ItemSearchBrowsePane.class);
private final FolderSelectionModel folderSelectionModel;
private final FolderRequestLocal folderRequestLocal;
private final Tree tree;
private ItemSearchFolderBrowser folderBrowser;
private SingleSelect sectionSelect;
private SingleSelectionModel typeSelectionModel;
public ItemSearchBrowsePane() {
final LayoutPanel mainPanel = new LayoutPanel();
setClassAttr("sidebarNavPanel");
setAttribute("navbar-title",
new GlobalizedMessage("cms.ui.folder_browser",
CmsConstants.CMS_BUNDLE)
.localize().toString());
final BoxPanel left = new BoxPanel(BoxPanel.VERTICAL);
final Label label = new Label(new GlobalizedMessage(
"cms.ui.folder_browser", CmsConstants.CMS_BUNDLE));
label.setClassAttr("heading");
left.add(label);
// As described in ticket 20540, some clients do not want the option to pick items from other
// subsites through the ItemSearchBrowsePane. A new parameter has been added to allow the
// administrator to pick between the old and new versions.
boolean linksOnlyInSameSubsite = CMSConfig.getConfig()
.isLinksOnlyInSameSubsite();
LOGGER.debug("linksOnlyInSameSubsite value is {}",
linksOnlyInSameSubsite);
tree = new Tree(new FolderTreeModelBuilder() {
@Override
protected Category getRootFolder(final PageState state) {
final Category root = ItemSearchBrowsePane.this.getRootFolder(
state);
if (null == root) {
return super.getRootFolder(state);
}
return root;
}
});
folderSelectionModel = createFolderSelectionModel();
folderSelectionModel.addChangeListener(this);
folderRequestLocal = new FolderRequestLocal(folderSelectionModel);
if (!linksOnlyInSameSubsite) {
// The client should be able to pick between the subsites
Form sectionForm = getSectionForm();
add(sectionForm);
}
tree.setSelectionModel(folderSelectionModel);
tree.setClassAttr("navbar");
tree.addTreeExpansionListener(this);
left.add(tree);
left.setClassAttr("main");
final BoxPanel body = new BoxPanel(BoxPanel.VERTICAL);
folderBrowser = new ItemSearchFolderBrowser(folderSelectionModel);
body.add(folderBrowser);
body.add(folderBrowser.getPaginator());
mainPanel.setLeft(left);
mainPanel.setBody(body);
add(mainPanel);
}
@Override
public boolean isVisible(final PageState state) {
// Always expand root node
if (tree.isCollapsed(Long.toString(getRootFolder(state).getObjectId()),
state)) {
tree.expand(Long.toString(getRootFolder(state).getObjectId()),
state);
}
return super.isVisible(state);
}
private Form getSectionForm() {
final Form sectionForm = new Form("isfbSectionForm",
new BoxPanel(BoxPanel.HORIZONTAL));
sectionForm.setClassAttr("navbar");
sectionSelect = new SingleSelect(new LongParameter("isfbSection"));
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ContentSectionRepository sectionRepo = cdiUtil.findBean(
ContentSectionRepository.class);
final List sections = sectionRepo.findAll();
sections.forEach(section -> sectionSelect.addOption(
new Option(Long.toString(section.getObjectId()),
section.getDisplayName())));
sectionForm.addInitListener(new FormInitListener() {
@Override
public void init(final FormSectionEvent event) {
final PageState state = event.getPageState();
if (null == sectionSelect.getValue(state)) {
ContentSection section = CMS.getContext().
getContentSection();
sectionSelect.setValue(state, section.getObjectId());
}
}
});
sectionForm.add(sectionSelect);
sectionForm.add(new Submit("Change Section"));
return sectionForm;
}
private Folder getRootFolder(final PageState state) {
LOGGER.debug("Getting the root folder.");
if (sectionSelect != null) {
// We have more than one subsite to choose between
final Long sectionId = (Long) sectionSelect.getValue(state);
if (LOGGER.isDebugEnabled()) {
if (null == sectionId) {
LOGGER.debug("Using default section");
} else {
LOGGER.debug("Using section " + sectionId.toString());
}
}
if (null == sectionId) {
return null;
}
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ContentSectionRepository sectionRepo = cdiUtil.findBean(
ContentSectionRepository.class);
final ContentSection section = sectionRepo.findById(sectionId);
return section.getRootDocumentsFolder();
} else {
return null;
}
}
@Override
public void register(final Page page) {
super.register(page);
page.addComponentStateParam(this, folderSelectionModel
.getStateParameter());
// Only add the SingleSelect item if it exists
if (sectionSelect != null) {
page.addComponentStateParam(this, sectionSelect.getParameterModel());
}
// Save the state of the new item component
// p.addComponentStateParam(this, m_typeSel.getStateParameter());
page.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
final PageState state = event.getPageState();
if (state.isVisibleOnPage(ItemSearchBrowsePane.this)) {
showHideSegments(state);
}
}
});
}
/**
* Show/hide segments based on access checks.
*
* @param state The page state
*/
private void showHideSegments(final PageState state) {
//Empty
}
@Override
public void reset(final PageState state) {
//Empty
}
public ItemSearchFolderBrowser getFolderBrowser() {
return folderBrowser;
}
public final FolderSelectionModel getFolderSelectionModel() {
return folderSelectionModel;
}
/**
* sets the current level of expansion of the folder tree and in the folder
* browser table
*
* @param state
* @param key
*/
protected void setSelectedFolder(final PageState state,
final String key) {
//set the selected folder of the folder browser
folderBrowser.getFolderSelectionModel().setSelectedKey(
state, Long.parseLong(key));
//set the selected folder of the folder tree
folderSelectionModel.setSelectedKey(state, Long.parseLong(key));
final Folder current = (Folder) folderSelectionModel.getSelectedObject(
state);
final Folder parent = current.getParentFolder();
if (parent != null) {
final long parentId = parent.getObjectId();
tree.expand(Long.toString(parentId), state);
}
}
// Implement TreeExpansionListener
@Override
public void treeCollapsed(final TreeExpansionEvent event) {
final PageState state = event.getPageState();
folderSelectionModel.setSelectedKey(
state, Long.parseLong((String) event.getNodeKey()));
}
@Override
public void treeExpanded(final TreeExpansionEvent event) {
// Empty
}
@Override
public void stateChanged(final ChangeEvent event) {
final PageState state = event.getPageState();
final Folder current = (Folder) folderSelectionModel.getSelectedObject(state);
final Folder parent = current.getParentFolder();
folderBrowser.getPaginator().reset(state);
if (parent != null) {
final Long parentId = parent.getObjectId();
tree.expand(parentId.toString(), state);
}
}
@Override
public void process(final FormSectionEvent event) {
final PageState state = event.getPageState();
browseMode(state);
}
@Override
public void submitted(final FormSectionEvent event) {
//Nothing
}
private void browseMode(final PageState state) {
typeSelectionModel.clearSelection(state);
}
private void newItemMode(final PageState state) {
//Nothing
}
private FolderSelectionModel createFolderSelectionModel() {
return new FolderSelectionModel("folder") {
@Override
protected Long getRootFolderID(final PageState state) {
final Folder root = getRootFolder(state);
if (null == root) {
return super.getRootFolderID(state);
}
return root.getObjectId();
}
};
}
}