libreccm-legacy/ccm-docmgr/src/com/arsdigita/cms/docmgr/ui/CreateDocLinkPane.java

487 lines
19 KiB
Java
Executable File

/*
* Copyright (C) 2001 - 2003 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.
*
* Created on Dec 18, 2003
*
*/
package com.arsdigita.cms.docmgr.ui;
import com.arsdigita.bebop.*;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.MultipleSelect;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.ArrayParameter;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
import com.arsdigita.bebop.parameters.URLParameter;
import com.arsdigita.bebop.util.Color;
import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryCollection;
import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentSectionCollection;
import com.arsdigita.cms.docmgr.DocFolder;
import com.arsdigita.cms.docmgr.DocLink;
import com.arsdigita.cms.docmgr.DocMgr;
import com.arsdigita.cms.docmgr.search.SearchResults;
import com.arsdigita.cms.docmgr.search.SearchUtils;
import com.arsdigita.dispatcher.ObjectNotFoundException;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.KernelExcursion;
import com.arsdigita.kernel.User;
import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.util.StringUtils;
import com.arsdigita.util.UncheckedWrapperException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import org.apache.log4j.Logger;
/**
* A UI Container class used to create instances of <code>DocLink</code> object
* type.
*
* Contains a simple Search Form to search Documents by name. A table to display
* the results the of the search. ActionLinks in the action column of
* <code>CreateDocLinkSearchTable</code> are responsible to actually create the
* Links to the Document represented in the corresponding row of the table.
*
* @author <a href="mailto:sshinde@redhat.com">Shashin Shinde</a>
*
* $Id:
* //apps/docmgr-cms/dev/src/com/arsdigita/cms/docmgr/ui/CreateDocLinkPane.java#2
* $
*
*/
public class CreateDocLinkPane extends SimpleContainer
implements DMConstants {
private static final Logger s_log = Logger.getLogger(
CreateDocLinkPane.class.getName());
public static final String PARAM_EDIT_DOCLINK_ID = "editDoclinkID";
private static final String SEARCH_DOCUMENT = "searchDocument";
private static final String TITLE = "title";
private static final String DESCRIPTION = "description";
private static final String EXTERNAL_URL = "url";
private static final String CATEGORIES = "file-edit-cats";
private final BigDecimalParameter m_doclinkIDParam =
new BigDecimalParameter(PARAM_EDIT_DOCLINK_ID);
private final TrimmedStringParameter m_searchDocsParam =
new TrimmedStringParameter(SEARCH_DOCUMENT);
private Label m_emptyLabel;
private Label m_errorMessages;
private Tree m_tree;
private Paginator m_paginator;
/**
* Constructor.
*
* @param parent to which this Table is added.Used to return after creating
* the link and cleaning up the Table selection.
* @param tree.Tree object to get the currently selected parent Folder under
* which to create the link.
* @param form.Search Form to get the terms to search for.
*/
public CreateDocLinkPane(Component parent, Tree tree) {
m_tree = tree;
//Main Container.
//ColumnPanel m_mainContainer = new ColumnPanel(ColumnPanel.VERTICAL, true);
ColumnPanel m_mainContainer = new ColumnPanel(1);
add(new Label(" "));
add(new Label(" "));
add(new Label(new GlobalizedMessage("ui.link.create.explanation", BUNDLE_NAME)),
ColumnPanel.LEFT);
URLEntryForm m_entryForm = new URLEntryForm(new GridPanel(2), parent);
m_mainContainer.add(m_entryForm);
m_mainContainer.add(new Label(" "));
m_mainContainer.add(new Label(" "));
//Add form at the top.
SearchForm topSearchForm = new DocumentSearchForm(new GridPanel(2));
m_mainContainer.add(topSearchForm);
m_mainContainer.add(new Label(" &nbsp; &nbsp; ", false));
//Bottom SegmentedPanel
SegmentedPanel bottom = new SegmentedPanel();
bottom.setClassAttr("main");
//Header for the Bottom panel which displays the results.
ModalContainer m_segmentHeader = new ModalContainer();
m_emptyLabel = new Label("Search Results");
m_segmentHeader.add(m_emptyLabel);
m_segmentHeader.setDefaultComponent(m_emptyLabel);
//Search Results Component.
final CreateDocLinkSearchTable m_search =
new CreateDocLinkSearchTable(this, parent, tree, topSearchForm);
m_entryForm.addInitListener(new FormInitListener() {
public void init(FormSectionEvent e) throws FormProcessException {
m_search.clearSelection(e.getPageState());
e.getPageState().setValue(m_searchDocsParam, null);
}
});
m_paginator = new Paginator(
(PaginationModelBuilder) m_search.getModelBuilder(),
CreateDocLinkSearchTable.PAGE_SIZE);
bottom.addSegment(m_segmentHeader, m_paginator);
m_paginator.setHiddenIfSinglePage(false);
m_mainContainer.add(bottom);
m_errorMessages = new Label("");
// DEPRECATED! The theme decides how to display a error message.
// m_errorMessages.setColor(Color.red);
m_mainContainer.add(m_errorMessages);
//Add Search Results table
m_mainContainer.add(m_search);
add(m_mainContainer);
}
/*
* Register state parameters
*/
public void register(Page p) {
super.register(p);
p.addGlobalStateParam(m_doclinkIDParam);
p.addGlobalStateParam(m_searchDocsParam);
}
Label getErrorLable() {
return m_errorMessages;
}
public BigDecimalParameter getEditDoclinkIDParam() {
return m_doclinkIDParam;
}
private class URLEntryForm extends Form
implements FormInitListener,
FormValidationListener,
FormProcessListener {
// public static final String PARAM_DOC_LINK_ID = "doclinkID";
private Submit m_submit;
TrimmedStringParameter m_title;
TrimmedStringParameter m_description;
URLParameter m_URL;
ArrayParameter m_cats;
Component m_parent;
// BigDecimalParameter m_doclinkID = new BigDecimalParameter(PARAM_DOC_LINK_ID);
public URLEntryForm(Container panel, Component parent) {
super("urlEntry", panel);
setMethod(Form.POST);
m_parent = parent;
m_title = new TrimmedStringParameter(TITLE);
m_description = new TrimmedStringParameter(DESCRIPTION);
m_URL = new URLParameter(EXTERNAL_URL);
add(new Label("Title:"));
TextField title = new TextField(m_title);
// title.addValidationListener(new NotEmptyValidationListener());
add(title);
add(new Label("Description (optional):"));
// TextField desc = new TextField(m_description);
// desc.setSize(70);
TextArea desc = new TextArea(m_description);
desc.setRows(10);
desc.setCols(40);
add(desc);
add(new Label("URL (must begin with \"http://\" or \"https://\"):"));
TextField url = new TextField(m_URL);
url.setSize(70);
// url.addValidationListener(new NotEmptyValidationListener());
// url.addValidationListener(new URLValidationListener());
add(url);
add(new Label(FILE_CATEGORIES));
m_cats = new ArrayParameter(CATEGORIES);
MultipleSelect catSelect = new MultipleSelect(CATEGORIES);
catSelect.setSize(20);
try {
catSelect.addPrintListener(new CategoriesPrintListener(
getContentSection(),
getEditDoclinkIDParam()));
} catch (java.util.TooManyListenersException tmex) {
throw new UncheckedWrapperException(tmex.getMessage());
}
add(catSelect);
m_submit = new Submit("submitButton", "Save Link");
add(m_submit, GridPanel.RIGHT);
add(new Submit("cancelButton", "Cancel"));
// add(new Hidden(m_doclinkID));
addInitListener(this);
addValidationListener(this);
addProcessListener(this);
}
private ContentSection getContentSection() {
ContentSectionCollection csc = ContentSection.getAllSections();
csc.addEqualsFilter("label", DocMgr.getConfig().getContentSection());
if (!csc.next()) {
csc.close();
return null;
}
ContentSection cs = csc.getContentSection();
csc.close();
return cs;
}
public void init(FormSectionEvent e) {
PageState state = e.getPageState();
BigDecimal id = (BigDecimal) state.getValue(m_doclinkIDParam);
if (id != null) {
DocLink doclink = new DocLink(id);
FormData fd = e.getFormData();
// fd.put(PARAM_DOC_LINK_ID, id);
if (doclink.isExternal()) {
fd.put(TITLE, doclink.getTitle());
fd.put(DESCRIPTION, doclink.getDescription());
fd.put(EXTERNAL_URL, doclink.getExternalURL());
ArrayList assignedCats = new ArrayList();
CategoryCollection cats = doclink.getCategoryCollection();
Category cat;
if (cats.next()) {
cat = cats.getCategory();
String catID = cat.getID().toString();
assignedCats.add(catID);
}
fd.put(CATEGORIES, assignedCats.toArray());
}
}
}
public void validate(FormSectionEvent e) throws FormProcessException {
PageState state = e.getPageState();
if (m_submit.isSelected(state)) {
FormData fd = e.getFormData();
String title = (String) fd.get(TITLE);
if (title == null || title.trim().length() == 0) {
fd.addError(TITLE, "This parameter is required");
}
//validate length of title
if (title != null && title.length() > 1000) {
fd.addError(TITLE, "This parameter is too long. It must be fewer than 1000 characters.");
}
String url = (String) fd.get(EXTERNAL_URL);
if (url == null || url.trim().length() == 0) {
fd.addError(EXTERNAL_URL, "This parameter is required");
}
if (url != null && url.length() > 4000) {
fd.addError(EXTERNAL_URL, "This parameter is too long. It must be fewer than 4000 characters.");
}
try {
new URL(url);
} catch (MalformedURLException ex) {
fd.addError(EXTERNAL_URL, "Please enter a URL");
}
//validate length of description
String desc = (String) fd.get(DESCRIPTION);
if (desc != null && desc.length() > 4000) {
fd.addError(DESCRIPTION, "This parameter is too long. It must be fewer than 4000 characters.");
}
}
}
/**
* Just a dummy run to cache the results in RequestLocal object.
*/
public void process(FormSectionEvent e) {
PageState state = e.getPageState();
FormData fd = e.getFormData();
if (m_submit.isSelected(state)) {
final DocFolder parent = getSelectedFolder(state);
ContentBundle bundle;
//Reached here indicates we can now proceed with Link Creation.
DocLink link;
BigDecimal id = (BigDecimal) state.getValue(m_doclinkIDParam);
if (id != null) {
link = new DocLink(id);
bundle = link.getContentBundle();
} else {
link = new DocLink();
link.setName((String) fd.get(TITLE));
//FIXME: when our client decides upon what permissions
// to adopt , change this one
//and permissions code accordingly.
link.setRepository(DocFolder.getRepository(parent));
link.setLanguage("en");
bundle = new ContentBundle(link);
bundle.setParent(parent);
bundle.setContentSection(parent.getContentSection());
bundle.save();
final ContentBundle bundleFinal = bundle;
new KernelExcursion() {
protected void excurse() {
setParty(Kernel.getSystemParty());
PermissionService.setContext(bundleFinal, parent);
}
}.run();
}
link.setName((String) fd.get(TITLE));
link.setTitle((String) fd.get(TITLE));
link.setDescription((String) fd.get(DESCRIPTION));
link.setExternalURL((String) fd.get(EXTERNAL_URL));
link.setCategories((String[]) fd.get(CATEGORIES));
//((Table) e.getSource()).clearSelection(state);
}
((BrowsePane) m_parent).displayFolderContentPanel(state);
}
}
/**
* A Form to Search Documents by name.Has one simple
* <code>TextField</code> and a submit button.
*
* It caches the SearchResults object in the m_coin RequestLocal object.
*
*/
private class DocumentSearchForm extends Form
implements SearchForm,
FormValidationListener,
FormProcessListener,
FormInitListener {
private Submit m_submit;
private RequestLocal m_validated;
private RequestLocal m_coln;
public DocumentSearchForm(Container panel) {
super("docSearch", panel);
setMethod(Form.GET);
add(new Label("Search text:"));
TextField searchText = new TextField(SEARCH_DOCUMENT);
add(searchText);
m_submit = new Submit("search", "Search");
add(m_submit);
addValidationListener(this);
addProcessListener(this);
addInitListener(this);
m_coln = new RequestLocal();
m_validated = new RequestLocal();
}
public void init(FormSectionEvent e) throws FormProcessException {
e.getFormData().setParameter(SEARCH_DOCUMENT, null);
}
public void validate(FormSectionEvent e) throws FormProcessException {
PageState ps = e.getPageState();
String docsSearch = (String) ps.getValue(m_searchDocsParam);
if (StringUtils.emptyString(docsSearch)) {
m_emptyLabel.setVisible(ps, true);
m_validated.set(ps, new Boolean(false));
throw new FormProcessException(
"At least one search parameter must be specified");
}
m_validated.set(ps, new Boolean(true));
//Reset the paginator for new search.
m_paginator.reset(ps);
}
/**
* Just a dummy run to cache the results in RequestLocal object.
*/
public void process(FormSectionEvent e) {
PageState state = e.getPageState();
if (m_submit.isSelected(state)
&& ((Boolean) m_validated.get(state)).booleanValue()) {
SearchResults results = getSearchHits(state);
if (results != null
&& results.getTotalSize() > 0) {
s_log.debug("results");
} else {
s_log.debug("no results");
}
}
}
/**
* Cache the results in the upper class's RequestLocal object.
*/
public SearchResults getSearchHits(PageState state) {
SearchResults searchResults = (SearchResults) m_coln.get(state);
String terms = (String) state.getValue(m_searchDocsParam);
s_log.debug("terms is " + terms);
if (searchResults == null && !StringUtils.emptyString(terms)) {
User user = (User) Kernel.getContext().getParty();
searchResults = SearchUtils.getSimpleSearch(terms, user);
m_coln.set(state, searchResults);
}
return searchResults;
}
@Override
public boolean isVisible(PageState state) {
return true;
}
public long getSearchResultCount(PageState state) {
return m_coln.get(state) == null ? 0
: ((SearchResults) m_coln.get(state)).getTotalSize();
}
}
/**
* Helper method to return the currently Selected Parent Folder in the tree
*/
private DocFolder getSelectedFolder(PageState state) {
DocFolder p = null;
String selKey = (String) m_tree.getSelectedKey(state);
if (selKey == null) {
p = DMUtils.getRootFolder(state);
} else {
BigDecimal folderID = new BigDecimal(selKey);
try {
p = new DocFolder(folderID);
} catch (DataObjectNotFoundException nf) {
throw new ObjectNotFoundException(
(String) FOLDER_PARENTNOTFOUND_ERROR.localize(state
.getRequest()));
}
}
return p;
}
}