libreccm-legacy/ccm-cms/src/com/arsdigita/cms/ui/workflow/TaskItemPane.java

526 lines
18 KiB
Java
Executable File

/*
* Copyright (C) 2003-2004 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.cms.ui.workflow;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.TableActionAdapter;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.ui.BaseItemPane;
import com.arsdigita.cms.ui.VisibilityComponent;
import com.arsdigita.cms.workflow.CMSEngine;
import com.arsdigita.cms.workflow.CMSTask;
import com.arsdigita.kernel.EmailAddress;
import com.arsdigita.kernel.Group;
import com.arsdigita.kernel.GroupCollection;
import com.arsdigita.kernel.User;
import com.arsdigita.kernel.UserCollection;
import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.PropertyList;
import com.arsdigita.toolbox.ui.Section;
import com.arsdigita.util.LockableImpl;
import com.arsdigita.web.Web;
import com.arsdigita.workflow.simple.Engine;
import com.arsdigita.workflow.simple.TaskCollection;
import com.arsdigita.workflow.simple.Workflow;
import java.math.BigDecimal;
import java.util.Collection;
/*
* @author Justin Ross <jross@redhat.com>
* @version $Id: TaskItemPane.java 1280 2006-07-27 09:12:09Z cgyg9330 $
*/
final class TaskItemPane extends BaseItemPane {
private final WorkflowRequestLocal m_workflow;
private final TaskRequestLocal m_task;
private final SimpleContainer m_detailPane;
TaskItemPane(final WorkflowRequestLocal workflow,
final TaskRequestLocal task,
final ActionLink finishLink,
final ActionLink editLink,
final ActionLink deleteLink,
final ActionLink backLink) {
m_workflow = workflow;
m_task = task;
m_detailPane = new SimpleContainer();
m_detailPane.add(new Navigation(backLink));
m_detailPane.add(new SummarySection(finishLink, editLink, deleteLink));
// Users
final ActionLink userAddLink = new ActionLink
(new Label(gz("cms.ui.workflow.task.user.add")));
final TaskAddUser userAddPane = new TaskAddUser(m_task);
final Form search = userAddPane.getSearchForm();
final Form add = userAddPane.getAddForm().getForm();
m_detailPane.add(new UserSection(userAddLink));
// Roles
final ActionLink roleAddLink = new ActionLink
(new Label(gz("cms.ui.workflow.task.role.add")));
final TaskAddRole roleAddForm = new TaskAddRole(m_task);
m_detailPane.add(new RoleSection(roleAddLink));
add(m_detailPane);
setDefault(m_detailPane);
add(userAddPane);
add(roleAddForm);
userAddLink.addActionListener(new NavigationListener(userAddPane));
search.addSubmissionListener(new CancelListener(search));
add.addSubmissionListener(new CancelListener(add));
add.addProcessListener(new FormNavigationListener(m_detailPane));
connect(roleAddLink, roleAddForm);
resume(roleAddForm, m_detailPane);
}
private boolean hasAdmin(final PageState state) {
final SecurityManager sm = CMS.getContext().getSecurityManager();
return sm.canAccess(state.getRequest(), WORKFLOW_ADMIN);
}
private class AdminVisible extends VisibilityComponent {
public AdminVisible(final Component child) {
super(child, WORKFLOW_ADMIN);
}
}
private class AssigneeVisible extends AdminVisible {
private final Component m_child;
private final Assigned m_assigned;
public AssigneeVisible(final Component child) {
super(child);
m_child = child;
m_assigned = new Assigned();
}
public final boolean isVisible(final PageState state) {
if (m_child.isVisible(state)) {
return m_assigned.isAssigned(state) || hasPermission(state);
} else {
return false;
}
}
private class Assigned extends RequestLocal {
protected final Object initialValue(final PageState state) {
if (assigned(state)) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
private boolean assigned(final PageState state) {
final Workflow workflow = m_workflow.getWorkflow(state);
final User user = Web.getWebContext().getUser();
final CMSTask task = m_task.getTask(state);
final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE);
final Collection tasks = engine.getEnabledTasks
(user, workflow.getID());
return tasks.contains(task);
}
final boolean isAssigned(final PageState state) {
return ((Boolean) get(state)).booleanValue();
}
}
}
private class VisibilityListener implements ActionListener {
private final TableColumn m_column;
VisibilityListener(final TableColumn column) {
m_column = column;
}
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
if (state.isVisibleOnPage(TaskItemPane.this) && !hasAdmin(state)) {
m_column.setVisible(state, false);
}
}
}
private class Navigation extends ActionGroup {
Navigation(final ActionLink backLink) {
addAction(backLink, ActionGroup.RETURN);
}
}
private class SummarySection extends Section {
SummarySection(final ActionLink finishLink,
final ActionLink editLink,
final ActionLink deleteLink) {
setHeading(new Label(gz("cms.ui.workflow.task.details")));
final ActionGroup group = new ActionGroup();
setBody(group);
group.setSubject(new Properties());
group.addAction(new AssigneeVisible(new LockLink()));
group.addAction(new AssigneeVisible(new UnlockLink()));
group.addAction(new AssigneeVisible(finishLink));
group.addAction(new AdminVisible(editLink), ActionGroup.EDIT);
group.addAction(new AdminVisible(deleteLink), ActionGroup.DELETE);
}
private class LockLink extends ActionLink {
LockLink() {
super(new Label(gz("cms.ui.workflow.task.lock")));
addActionListener(new Listener());
}
public final boolean isVisible(final PageState state) {
final CMSTask task = m_task.getTask(state);
return task.isEnabled() && !task.isLocked();
}
private class Listener implements ActionListener {
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
if (hasAdmin(state)) {
final CMSTask task = m_task.getTask(state);
task.lock(Web.getWebContext().getUser());
task.save();
}
}
}
}
private class UnlockLink extends ActionLink {
UnlockLink() {
super(new Label(gz("cms.ui.workflow.task.unlock")));
addActionListener(new Listener());
}
public final boolean isVisible(final PageState state) {
final CMSTask task = m_task.getTask(state);
return task.isEnabled() && task.isLocked();
}
private class Listener implements ActionListener {
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
if (hasAdmin(state)) {
final CMSTask task = m_task.getTask(state);
task.unlock(Web.getWebContext().getUser());
task.save();
}
}
}
}
private class Properties extends PropertyList {
protected final java.util.List properties(final PageState state) {
final java.util.List props = super.properties(state);
final CMSTask task = m_task.getTask(state);
props.add(new Property(gz("cms.ui.name"),
task.getLabel()));
props.add(new Property(gz("cms.ui.description"),
task.getDescription()));
props.add(new Property(gz("cms.ui.workflow.task.dependencies"),
deps(task)));
props.add(new Property(gz("cms.ui.workflow.task.state"),
task.getStateString()));
props.add(new Property(gz("cms.ui.workflow.task.locked"),
task.isLocked()
? lz("cms.ui.yes") : lz("cms.ui.no")));
return props;
}
private String deps(final CMSTask task) {
final TaskCollection deps = task.getRequiredTasks();
final StringBuffer buffer = new StringBuffer();
while (deps.next()) {
buffer.append(deps.getTask().getLabel() + ", ");
}
final int len = buffer.length();
if (len >= 2) {
buffer.setLength(len - 2);
}
deps.close();
return buffer.toString();
}
}
}
private class UserSection extends Section {
public UserSection(final ActionLink userAddLink) {
setHeading(new Label(gz("cms.ui.workflow.task.users")));
final ActionGroup group = new ActionGroup();
setBody(group);
group.setSubject(new UserTable());
group.addAction(new AdminVisible(userAddLink), ActionGroup.ADD);
}
}
private class UserTable extends Table {
public UserTable() {
super(new UserTableModelBuilder(m_task),
new String[] {
lz("cms.ui.name"), // XXX globz
lz("cms.ui.email"),
lz("cms.ui.workflow.task.user.delete")
});
setEmptyView(new Label(gz("cms.ui.workflow.task.user.none")));
getColumn(2).setCellRenderer(new DefaultTableCellRenderer(true));
addTableActionListener(new TableActionAdapter() {
public final void cellSelected(final TableActionEvent e) {
final PageState state = e.getPageState();
final int column = e.getColumn().intValue();
if (column == 2) {
if (hasAdmin(state)) {
final CMSTask task = m_task.getTask(state);
final BigDecimal id = new BigDecimal
((String) e.getRowKey());
task.removeUser(User.retrieve(id));
task.save();
}
}
}
});
}
public final void register(final Page page) {
super.register(page);
page.addActionListener
(new VisibilityListener(getColumn(2)));
}
}
private static class UserTableModelBuilder extends LockableImpl
implements TableModelBuilder {
private final TaskRequestLocal m_task;
public UserTableModelBuilder(final TaskRequestLocal task) {
m_task = task;
}
public final TableModel makeModel(final Table table,
final PageState state) {
return new Model(m_task.getTask(state));
}
private class Model implements TableModel {
private User m_user;
private final UserCollection m_users;
private Model(final CMSTask task) {
m_users = task.getAssignedUserCollection();
}
public final int getColumnCount() {
return 3;
}
public final boolean nextRow() {
if (m_users.next()) {
m_user = m_users.getUser();
return true;
} else {
m_users.close();
return false;
}
}
public final Object getKeyAt(final int column) {
return m_user.getID().toString();
}
public final Object getElementAt(final int column) {
switch (column) {
case 0:
return m_user.getName();
case 1:
final EmailAddress email = m_user.getPrimaryEmail();
if (email == null) {
return "";
} else {
return email.toString();
}
case 2:
return lz("cms.ui.workflow.task.user.delete");
default:
throw new IllegalStateException();
}
}
}
}
private class RoleSection extends Section {
public RoleSection(final ActionLink roleAddLink) {
setHeading(new Label(gz("cms.ui.workflow.task.roles")));
final ActionGroup group = new ActionGroup();
setBody(group);
group.setSubject(new RoleTable());
group.addAction(new AdminVisible(roleAddLink), ActionGroup.ADD);
}
}
private class RoleTable extends Table {
public RoleTable() {
super(new RoleTableModelBuilder(m_task),
new String[] {
lz("cms.ui.name"), // XXX globz
lz("cms.ui.workflow.task.role.delete")
});
setEmptyView(new Label(gz("cms.ui.workflow.task.role.none")));
getColumn(1).setCellRenderer(new DefaultTableCellRenderer(true));
addTableActionListener(new TableActionAdapter() {
public final void cellSelected(final TableActionEvent e) {
final PageState state = e.getPageState();
final int column = e.getColumn().intValue();
if (column == 1) {
if (hasAdmin(state)) {
final CMSTask task = m_task.getTask(state);
final BigDecimal id = new BigDecimal
((String) e.getRowKey());
task.removeGroup(new Group(id));
task.save();
}
}
}
});
}
public final void register(final Page page) {
super.register(page);
page.addActionListener
(new VisibilityListener(getColumn(1)));
}
}
private static class RoleTableModelBuilder extends LockableImpl
implements TableModelBuilder {
private final TaskRequestLocal m_task;
public RoleTableModelBuilder(final TaskRequestLocal task) {
m_task = task;
}
public final TableModel makeModel(final Table table,
final PageState state) {
return new Model(m_task.getTask(state));
}
private class Model implements TableModel {
private Group m_role;
private final GroupCollection m_roles;
private Model(final CMSTask task) {
m_roles = task.getAssignedGroupCollection();
}
public final int getColumnCount() {
return 2;
}
public final boolean nextRow() {
if (m_roles.next()) {
m_role = m_roles.getGroup();
return true;
} else {
m_roles.close();
return false;
}
}
public final Object getKeyAt(final int column) {
return m_role.getID().toString();
}
public final Object getElementAt(final int column) {
switch (column) {
case 0:
return m_role.getName();
case 1:
return lz("cms.ui.workflow.task.role.delete");
default:
throw new IllegalStateException();
}
}
}
}
}