526 lines
18 KiB
Java
Executable File
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|