441 lines
14 KiB
Java
Executable File
441 lines
14 KiB
Java
Executable File
/*
|
|
* Copyright (C) 2001, 2002 Red Hat Inc. All Rights Reserved.
|
|
*
|
|
* The contents of this file are subject to the CCM Public
|
|
* License (the "License"); you may not use this file except in
|
|
* compliance with the License. You may obtain a copy of
|
|
* the License at http://www.redhat.com/licenses/ccmpl.html
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
*/
|
|
|
|
package com.arsdigita.docmgr.ui;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
import java.util.ArrayList;
|
|
|
|
import com.arsdigita.bebop.ActionLink;
|
|
import com.arsdigita.bebop.BoxPanel;
|
|
import com.arsdigita.bebop.ColumnPanel;
|
|
import com.arsdigita.bebop.Component;
|
|
import com.arsdigita.bebop.Container;
|
|
import com.arsdigita.bebop.GridPanel;
|
|
import com.arsdigita.bebop.Label;
|
|
import com.arsdigita.bebop.Link;
|
|
import com.arsdigita.bebop.List;
|
|
import com.arsdigita.bebop.ModalContainer;
|
|
import com.arsdigita.bebop.Page;
|
|
import com.arsdigita.bebop.PageState;
|
|
import com.arsdigita.bebop.RequestLocal;
|
|
import com.arsdigita.bebop.SegmentedPanel;
|
|
import com.arsdigita.bebop.SimpleComponent;
|
|
import com.arsdigita.bebop.SimpleContainer;
|
|
import com.arsdigita.bebop.TabbedPane;
|
|
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.RequestEvent;
|
|
import com.arsdigita.bebop.event.RequestListener;
|
|
import com.arsdigita.bebop.list.ListCellRenderer;
|
|
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
|
import com.arsdigita.bebop.parameters.StringParameter;
|
|
import com.arsdigita.docmgr.File;
|
|
import com.arsdigita.docmgr.ResourceImpl;
|
|
import com.arsdigita.domain.DataObjectNotFoundException;
|
|
import com.arsdigita.globalization.GlobalizedMessage;
|
|
import com.arsdigita.xml.Element;
|
|
|
|
/**
|
|
* User Interface component of the Document Manager application which
|
|
* which serves as entry-point and navigation tool of the repositories
|
|
* that a user has subscribed too.
|
|
* The tree of all subscribed repositories is on the left side, the full
|
|
* listing of the currently selected directory is on the right side.
|
|
*
|
|
* @author <mailto href="StefanDeusch@computer.org">Stefan Deusch</a>
|
|
*
|
|
*/
|
|
class BrowsePane extends ModalContainer
|
|
implements DMConstants, ChangeListener, RequestListener {
|
|
|
|
private Component m_folderContent;
|
|
private Component m_destinationFolderPanel;
|
|
private Component m_newFileForm;
|
|
private Component m_newFolderForm;
|
|
private Component m_errorMsgPanel;
|
|
private DestinationFolderForm m_destinationFolderForm;
|
|
private ErrorMessageLabel m_errorMsgLabel;
|
|
private Container m_mainBrowseContainer;
|
|
|
|
private TabbedPane m_mainTabPane;
|
|
|
|
private Tree m_tree;
|
|
|
|
|
|
private BigDecimalParameter m_rootFolderIdParam = new BigDecimalParameter(ROOTFOLDER_ID_PARAM_NAME);
|
|
private BigDecimalParameter m_selFolderIdParam = new BigDecimalParameter(SEL_FOLDER_ID_PARAM_NAME);
|
|
private BigDecimalParameter m_fileIdParam = new BigDecimalParameter(FILE_ID_PARAM_NAME);
|
|
private StringParameter m_rootAddDocParam= new StringParameter(ROOT_ADD_DOC_PARAM_NAME);
|
|
|
|
/**
|
|
* Default constructor
|
|
*/
|
|
|
|
public BrowsePane() {
|
|
|
|
m_mainTabPane = new TabbedPane();
|
|
|
|
m_mainBrowseContainer = new BoxPanel();
|
|
m_mainTabPane.addTab(WS_BROWSE_TITLE,
|
|
m_mainBrowseContainer);
|
|
|
|
m_mainBrowseContainer.setClassAttr("sidebarNavPanel");
|
|
//m_mainBrowseContainer.setAttribute("navbar-title", "Folders");
|
|
|
|
BoxPanel leftSide = new BoxPanel();
|
|
leftSide.setClassAttr("navbar");
|
|
m_tree = new SuperTree(new RepositoriesSuperTreeModel());
|
|
m_tree.addChangeListener(this);
|
|
leftSide.add(m_tree);
|
|
|
|
m_mainBrowseContainer.add(leftSide);
|
|
|
|
/*
|
|
* Create all panels on the right side.
|
|
*/
|
|
|
|
SegmentedPanel rightSide = new SegmentedPanel();
|
|
rightSide.setClassAttr("main");
|
|
|
|
m_folderContent = makeContentPanel(rightSide);
|
|
|
|
m_mainBrowseContainer.add(rightSide);
|
|
|
|
add(m_mainTabPane);
|
|
|
|
m_newFileForm = makeFileUploadForm();
|
|
add(m_newFileForm);
|
|
|
|
m_newFolderForm = makeFolderCreateForm();
|
|
add(m_newFolderForm);
|
|
|
|
m_destinationFolderPanel = makeExpandFolderPanel();
|
|
add(m_destinationFolderPanel);
|
|
|
|
m_errorMsgPanel = makeErrorMsgPanel();
|
|
add(m_errorMsgPanel);
|
|
}
|
|
|
|
/**
|
|
* Register the page the fist time
|
|
*/
|
|
|
|
public void register(Page p) {
|
|
p.addGlobalStateParam(m_rootFolderIdParam);
|
|
p.addGlobalStateParam(m_selFolderIdParam);
|
|
p.addGlobalStateParam(m_rootAddDocParam);
|
|
p.addGlobalStateParam(m_fileIdParam);
|
|
|
|
p.addRequestListener(this);
|
|
|
|
super.register(p);
|
|
}
|
|
|
|
/**
|
|
* Checks if a folder is selected in the page state and consequently
|
|
* hides or shows the Folder Contents or Folder Action panels.
|
|
*/
|
|
public void pageRequested(RequestEvent e) {
|
|
PageState state = e.getPageState();
|
|
|
|
BigDecimal fid = (BigDecimal) state.getValue(m_fileIdParam);
|
|
|
|
boolean display = false;
|
|
String key = (String) m_tree.getSelectedKey(state);
|
|
|
|
// start out with root folder selected and open
|
|
if (key == null) {
|
|
key = DMUtils.getRootFolder(state).getID().toString();
|
|
m_tree.setSelectedKey(state, key);
|
|
display = true;
|
|
}
|
|
|
|
// need this only when coming from 1-file page
|
|
if (fid != null) {
|
|
try {
|
|
File file = new File(fid);
|
|
|
|
ResourceImpl parent = (ResourceImpl) file.getParent();
|
|
|
|
key = parent.getID().toString();
|
|
|
|
while (!parent.isRoot()) {
|
|
parent = (ResourceImpl) parent.getParent();
|
|
m_tree.expand(parent.getID().toString(), state);
|
|
}
|
|
} catch (DataObjectNotFoundException exc) {
|
|
exc.printStackTrace();
|
|
}
|
|
|
|
// to display this file's folder in the table
|
|
m_tree.setSelectedKey(state, key);
|
|
|
|
// now wipe out file param to avoid trouble elsewhere
|
|
state.setValue(m_fileIdParam, null);
|
|
}
|
|
|
|
// finally expand selected folder
|
|
m_tree.expand(key, state);
|
|
|
|
if (display) {
|
|
if( "t".equalsIgnoreCase(((String)state
|
|
.getValue(m_rootAddDocParam)))) {
|
|
// Entry hook to display FileUpload Form for Root folder
|
|
displayFileUpload(state);
|
|
} else {
|
|
displayFolderContentPanel(state);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Helper method to communicate selected folder ID to subcomponents.
|
|
* Return onle non-null after tree has been displayed at least once.
|
|
*/
|
|
|
|
public BigDecimal getFolderID(PageState state) {
|
|
return new BigDecimal((String) m_tree.getSelectedKey(state));
|
|
}
|
|
|
|
/**
|
|
* Implementation of the change listener, clicking on the folder
|
|
* loads the directory on the right side.
|
|
*/
|
|
|
|
public void stateChanged(ChangeEvent e) {
|
|
PageState state = e.getPageState();
|
|
|
|
// Display folder on the right side corresponding to the key
|
|
displayFolderContentPanel(state);
|
|
}
|
|
|
|
/**
|
|
* Build a panel to display the Folder content of the selected Folder
|
|
* and add it as a segment to the passed in Segmented Panel.
|
|
*/
|
|
|
|
private Component makeContentPanel(SegmentedPanel main) {
|
|
|
|
Label folder_info_header = new Label
|
|
(new GlobalizedMessage("ui.folder.content.header", BUNDLE_NAME));
|
|
folder_info_header.addPrintListener(
|
|
new FolderNamePrintListener(m_tree));
|
|
|
|
ActionLink newFileLink = new ActionLink(new Label(FOLDER_NEW_FILE_LINK));
|
|
newFileLink.setClassAttr("actionLink");
|
|
|
|
ActionLink newFolderLink =
|
|
new ActionLink(new Label(FOLDER_NEW_FOLDER_LINK));
|
|
newFolderLink.setClassAttr("actionLink");
|
|
|
|
newFileLink.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
displayFileUpload(e.getPageState());
|
|
}
|
|
});
|
|
|
|
newFolderLink.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
displayFolderCreate(e.getPageState());
|
|
}
|
|
});
|
|
|
|
GridPanel folderGrid = new GridPanel(1);
|
|
SimpleContainer pane = new SimpleContainer();
|
|
pane.add(newFileLink);
|
|
pane.add(new Label(" "));
|
|
pane.add(newFolderLink);
|
|
folderGrid.add(pane, GridPanel.RIGHT | GridPanel.BOTTOM);
|
|
folderGrid.add(new FolderContentsTableForm(this, m_tree),
|
|
GridPanel.LEFT | GridPanel.BOTTOM);
|
|
|
|
return main.addSegment(folder_info_header,
|
|
folderGrid);
|
|
}
|
|
|
|
/**
|
|
* Build File upload form
|
|
*/
|
|
private Component makeFileUploadForm() {
|
|
GridPanel gridPanel = new GridPanel(1);
|
|
|
|
Label fileUploadFormHeaderLabel = new Label(new GlobalizedMessage("ui.file.upload.header", BUNDLE_NAME));
|
|
fileUploadFormHeaderLabel.addPrintListener(
|
|
new FolderNamePrintListener(m_tree));
|
|
|
|
gridPanel.add(fileUploadFormHeaderLabel);
|
|
gridPanel.add(new FileUploadForm(this, m_tree));
|
|
|
|
return gridPanel;
|
|
|
|
}
|
|
|
|
/**
|
|
* Build Folder create form
|
|
*/
|
|
private Component makeFolderCreateForm() {
|
|
GridPanel gridPanel = new GridPanel(1);
|
|
Label folderCreateFormHeaderLabel = new Label
|
|
(new GlobalizedMessage("ui.folder.create.header", BUNDLE_NAME));
|
|
folderCreateFormHeaderLabel.addPrintListener(
|
|
new FolderNamePrintListener(m_tree));
|
|
|
|
gridPanel.add(folderCreateFormHeaderLabel);
|
|
gridPanel.add(new FolderCreateForm(this, m_tree));
|
|
return gridPanel;
|
|
|
|
}
|
|
|
|
/**
|
|
* Build a destination folders tree.
|
|
*/
|
|
private Component makeExpandFolderPanel() {
|
|
GridPanel gridPanel = new GridPanel(1);
|
|
gridPanel.add(DESTINATION_FOLDER_PANEL_HEADER);
|
|
m_destinationFolderForm = new DestinationFolderForm(this);
|
|
gridPanel.add(m_destinationFolderForm);
|
|
return gridPanel;
|
|
}
|
|
|
|
/*
|
|
* Build panel to display error message when copy/move failed.
|
|
*/
|
|
|
|
private Component makeErrorMsgPanel() {
|
|
ColumnPanel c = new ColumnPanel(1);
|
|
m_errorMsgLabel = new ErrorMessageLabel();
|
|
c.add(m_errorMsgLabel);
|
|
|
|
ActionLink link = new ActionLink(ACTION_ERROR_CONTINUE);
|
|
link.setClassAttr("actionLink");
|
|
link.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
displayFolderContentPanel(e.getPageState());
|
|
}
|
|
});
|
|
|
|
c.add(link);
|
|
return c;
|
|
}
|
|
|
|
public void displayFileUpload(PageState state) {
|
|
setVisibleComponent(state, m_newFileForm);
|
|
}
|
|
|
|
public void displayFolderCreate(PageState state) {
|
|
setVisibleComponent(state, m_newFolderForm);
|
|
}
|
|
|
|
public void displayFolderContentPanel(PageState state) {
|
|
setVisibleComponent(state, m_mainTabPane);
|
|
}
|
|
|
|
public void displayDestinationFolderPanel(PageState state,
|
|
Object[] resourceList,
|
|
boolean isMove) {
|
|
|
|
setVisibleComponent(state, m_destinationFolderPanel);
|
|
m_destinationFolderForm.setResourceList(state, resourceList);
|
|
if (isMove) {
|
|
m_destinationFolderForm.setMove(state);
|
|
} else {
|
|
m_destinationFolderForm.setCopy(state);
|
|
}
|
|
}
|
|
|
|
public void displayErrorMsgPanel(PageState state,
|
|
String action,
|
|
ArrayList list) {
|
|
|
|
m_errorMsgLabel.setMessages(state, action, list);
|
|
|
|
setVisibleComponent(state, m_errorMsgPanel);
|
|
}
|
|
|
|
|
|
/**
|
|
* Error message panel that allows to set customized error
|
|
* messages without showing a tomcat stacktrace
|
|
*/
|
|
|
|
private static class ErrorMessageLabel extends SimpleComponent
|
|
implements DMConstants {
|
|
|
|
private RequestLocal m_msgs;
|
|
private RequestLocal m_action;
|
|
|
|
public ErrorMessageLabel() {
|
|
m_msgs = new RequestLocal();
|
|
m_action = new RequestLocal();
|
|
|
|
}
|
|
|
|
/**
|
|
* Set list of file/folder that could not be delete/move/copy.
|
|
*
|
|
* @param action file operation (action, move, copy)
|
|
*/
|
|
|
|
public void setMessages(PageState state,
|
|
String action,
|
|
ArrayList msgs) {
|
|
m_action.set(state, action);
|
|
m_msgs.set(state, msgs);
|
|
}
|
|
|
|
public void generateXML(PageState state, Element parent) {
|
|
Element element = parent.newChildElement("docs:error-label",
|
|
DOCS_XML_NS);
|
|
element.addAttribute("action", (String) m_action.get(state));
|
|
|
|
ArrayList list = (ArrayList) m_msgs.get(state);
|
|
|
|
if (list != null) {
|
|
for (int i = 0; i < list.size(); i++) {
|
|
Element item = element.newChildElement("docs:item",
|
|
DOCS_XML_NS);
|
|
item.addAttribute("name", ((String) list.get(i)));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Table Cell Renderer that provides clickable Links to follow
|
|
* directory links .
|
|
*/
|
|
private static class DirLinkRenderer implements ListCellRenderer {
|
|
|
|
public Component getComponent(List list, PageState state,
|
|
Object value, String key,
|
|
int index, boolean isSelected) {
|
|
|
|
Link link = new Link((String)value,
|
|
"?" + SEL_FOLDER_ID_PARAM.getName() +
|
|
"=" + key);
|
|
return link;
|
|
}
|
|
}
|
|
}
|