ccm-core & ccm-cms incorporating
r1637 | chrisg23 | 2007-09-17 12:14:27 +0200 (Mo, 17 Sep 2007) Sourceforge patch 1796099 - allow URL Generators to be registered for specific content types. Requires upgrade script to be run: ccm-run ccm-cms --from-version 6.5.2 --to-version 6.5.3! ------------------------------------------------------------------------ r1638 | chrisg23 | 2007-09-17 13:48:34 +0200 (Mo, 17 Sep 2007) Sourceforge patch 1796156 - allow notes to be shown on basic properties authoring step ------------------------------------------------------------------------ r1639 | chrisg23 | 2007-09-17 15:20:13 +0200 (Mo, 17 Sep 2007) Sourceforge patch 1781131 - workaround to bypass query filtering bug if permission filtering folder contents ------------------------------------------------------------------------ r1641 | chrisg23 | 2007-09-17 15:46:27 +0200 (Mo, 17 Sep 2007) | 1 line Geänderte Pfade: M /trunk/ccm-core/src/com/arsdigita/notification/Notification.java Sourceforge patch 1714842 - if message delete has been specified for a notification, only delete it when the last referring notification is deleted (several notification records may refer to the same message) ------------------------------------------------------------------------ r1642 | chrisg23 | 2007-09-17 16:05:26 +0200 (Mo, 17 Sep 2007) | 1 line Sourceforge patch 1727634 - retain specified ordering when paging through folder contents (previously every time you changed to a new page it reverted to default name ordering) ------------------------------------------------------------------------ r1643 | chrisg23 | 2007-09-17 16:19:06 +0200 (Mo, 17 Sep 2007) | 1 line Sourceforge patch 1783195 - IMPORTANT BUGFIX - if you use fixed length lifecycles with expiry notifications then you are probably affected by this - notifications are not created and sent if you have relied on the default end date set by the lifecycle, only if you explicitly entered a date on the publish form. To fix the timebomb of items that are due to expire without notification, there is a command line program in package uk.gov.westsussex.wsgfl.jobs called CreateMissingNotificationPhases. Package is in ccm-wsx-wsgfl-custom module in contrib area of the repository. To use this, it is best to copy the job class and the accompanying pdl file query-missing-notification-phases to your own custom application, or else install ccm-wsx-wsgfl-custom but strip away everything except those 2 files and the initialiser - removing all bits of the initialiser except the data init. Do not add ccm-wsx-wsgfl-custom to your instance as it is, at it overrides some files in the default Aplaws installation git-svn-id: https://svn.libreccm.org/ccm/trunk@13 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
576ecedbd1
commit
5dcbb5e070
|
|
@ -2,11 +2,11 @@
|
||||||
<ccm:application xmlns:ccm="http://ccm.redhat.com/ccm-project"
|
<ccm:application xmlns:ccm="http://ccm.redhat.com/ccm-project"
|
||||||
name="ccm-cms"
|
name="ccm-cms"
|
||||||
prettyName="Red Hat CCM Content Management System"
|
prettyName="Red Hat CCM Content Management System"
|
||||||
version="6.5.2"
|
version="6.5.3"
|
||||||
release="4"
|
release="1"
|
||||||
webapp="ROOT">
|
webapp="ROOT">
|
||||||
<ccm:dependencies>
|
<ccm:dependencies>
|
||||||
<ccm:requires name="ccm-core" version="6.5.2" relation="ge"/>
|
<ccm:requires name="ccm-core" version="6.5.5" relation="ge"/>
|
||||||
</ccm:dependencies>
|
</ccm:dependencies>
|
||||||
<ccm:contacts>
|
<ccm:contacts>
|
||||||
<ccm:contact uri="http://www.redhat.com/software/ccm" type="website"/>
|
<ccm:contact uri="http://www.redhat.com/software/ccm" type="website"/>
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ model com.arsdigita.cms.workflow;
|
||||||
|
|
||||||
import com.arsdigita.workflow.simple.*;
|
import com.arsdigita.workflow.simple.*;
|
||||||
import com.arsdigita.kernel.ACSObject;
|
import com.arsdigita.kernel.ACSObject;
|
||||||
|
import com.arsdigita.cms.ContentType;
|
||||||
|
|
||||||
object type CMSTask extends UserTask {
|
object type CMSTask extends UserTask {
|
||||||
composite CMSTaskType [1..1] taskType = join cms_tasks.task_type_id to cms_task_types.task_type_id;
|
composite CMSTaskType [1..1] taskType = join cms_tasks.task_type_id to cms_task_types.task_type_id;
|
||||||
|
|
@ -36,6 +37,7 @@ object type CMSTaskType {
|
||||||
object type TaskEventURLGenerator {
|
object type TaskEventURLGenerator {
|
||||||
Integer [1..1] generatorID = cms_task_url_generators.generator_id INTEGER;
|
Integer [1..1] generatorID = cms_task_url_generators.generator_id INTEGER;
|
||||||
String [1..1] event = cms_task_url_generators.event VARCHAR(100);
|
String [1..1] event = cms_task_url_generators.event VARCHAR(100);
|
||||||
|
ContentType [0..1] contentType = join cms_task_url_generators.content_type to content_types.type_id;
|
||||||
String [1..1] urlGeneratorClass = cms_task_url_generators.classname VARCHAR(128);
|
String [1..1] urlGeneratorClass = cms_task_url_generators.classname VARCHAR(128);
|
||||||
|
|
||||||
object key (generatorID);
|
object key (generatorID);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
alter table CMS_TASK_URL_GENERATORS
|
||||||
|
add (content_type INTEGER);
|
||||||
|
|
||||||
|
alter table cms_task_url_generators add
|
||||||
|
constraint cms_tas_url_gen_con_ty_f_lz1y5 foreign key (content_type)
|
||||||
|
references content_types(type_id);
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 Chris Gilbert. 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
|
||||||
|
--
|
||||||
|
-- $Id: oracle-se-6.5.2-6.5.3.sql 293 2005-02-22 15:10:39Z cgilbert $
|
||||||
|
-- $DateTime: 2004/08/16 18:10:38 $
|
||||||
|
|
||||||
|
PROMPT Red Hat Enterprise CMS 6.5.2 -> 6.5.3 Upgrade Script (Oracle)
|
||||||
|
|
||||||
|
@@ ../default/upgrade/6.5.2-6.5.3/cms_task_url_generators_upgrade.sql
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 Chris Gilbert 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
|
||||||
|
--
|
||||||
|
-- $DateTime: 2004/08/17 23:15:09 $
|
||||||
|
|
||||||
|
\echo Red Hat Enterprise CMS 6.5.2 -> 6.5.3 Upgrade Script (PostgreSQL)
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
\i ../default/upgrade/6.5.2-6.5.3/cms_task_url_generators_upgrade.sql
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
@ -29,5 +29,8 @@
|
||||||
<version from="6.5.0" to="6.5.1">
|
<version from="6.5.0" to="6.5.1">
|
||||||
<script sql="ccm-cms/upgrade/::database::-6.5.0-6.5.1.sql"/>
|
<script sql="ccm-cms/upgrade/::database::-6.5.0-6.5.1.sql"/>
|
||||||
</version>
|
</version>
|
||||||
|
<version from="6.5.2" to="6.5.3">
|
||||||
|
<script sql="ccm-cms/upgrade/::database::-6.5.2-6.5.3.sql"/>
|
||||||
|
</version>
|
||||||
|
|
||||||
</upgrade>
|
</upgrade>
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,10 @@ import com.arsdigita.domain.DataObjectNotFoundException;
|
||||||
import com.arsdigita.domain.DomainObjectFactory;
|
import com.arsdigita.domain.DomainObjectFactory;
|
||||||
import com.arsdigita.domain.DomainCollectionIterator;
|
import com.arsdigita.domain.DomainCollectionIterator;
|
||||||
import com.arsdigita.kernel.ACSObject;
|
import com.arsdigita.kernel.ACSObject;
|
||||||
|
import com.arsdigita.kernel.Party;
|
||||||
import com.arsdigita.kernel.User;
|
import com.arsdigita.kernel.User;
|
||||||
import com.arsdigita.kernel.permissions.PermissionService;
|
import com.arsdigita.kernel.permissions.PermissionService;
|
||||||
|
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
|
||||||
import com.arsdigita.persistence.DataCollection;
|
import com.arsdigita.persistence.DataCollection;
|
||||||
import com.arsdigita.persistence.DataObject;
|
import com.arsdigita.persistence.DataObject;
|
||||||
import com.arsdigita.persistence.DataQuery;
|
import com.arsdigita.persistence.DataQuery;
|
||||||
|
|
@ -235,14 +237,13 @@ public class Folder extends ContentItem {
|
||||||
* @return child items of this folder
|
* @return child items of this folder
|
||||||
*/
|
*/
|
||||||
public ItemCollection getItems(boolean bSort) {
|
public ItemCollection getItems(boolean bSort) {
|
||||||
final DataQuery query = SessionManager.getSession().retrieveQuery
|
|
||||||
(ITEMS_QUERY);
|
|
||||||
|
|
||||||
query.setParameter(PARENT, getID());
|
DataQueryDataCollectionAdapter adapter = new DataQueryDataCollectionAdapter(ITEMS_QUERY, ITEM);
|
||||||
|
adapter.setParameter(PARENT, getID());
|
||||||
Assert.unequal(PENDING, getVersion());
|
Assert.unequal(PENDING, getVersion());
|
||||||
query.setParameter(VERSION, getVersion());
|
adapter.setParameter(VERSION, getVersion());
|
||||||
|
|
||||||
return new ItemCollection(query, bSort);
|
return new ItemCollection(adapter, bSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -593,12 +594,30 @@ public class Folder extends ContentItem {
|
||||||
private DataQuery m_query;
|
private DataQuery m_query;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param adapter an adapter constructed using the query name rather than a
|
||||||
|
* DataQuery object. This constructor must be used if there is any
|
||||||
|
* intention to permission filter the results as only a DataQueryDataCollectionAdapter
|
||||||
|
* constructed using query name has the bug fix to allow permission filtering
|
||||||
|
*
|
||||||
|
* @param bSort whether to sort the collection by isFolder and ID
|
||||||
|
*/
|
||||||
|
public ItemCollection (DataQueryDataCollectionAdapter adapter, boolean bSort) {
|
||||||
|
super(adapter);
|
||||||
|
doAlias(adapter);
|
||||||
|
init(adapter, bSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemCollection (DataQueryDataCollectionAdapter adapter) {
|
||||||
|
this(adapter, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param query the Data Query to use to retrieve the collection
|
* @param query the Data Query to use to retrieve the collection
|
||||||
* @param bSort whether to sort the collection by isFolder and ID
|
* @param bSort whether to sort the collection by isFolder and ID
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//ideally, we wouldn't sort the collection by default and only provide
|
//ideally, we wouldn't sort the collection by default and only provide
|
||||||
//one constructor. But, that would break the existing API
|
//one constructor. But, that would break the existing API
|
||||||
public ItemCollection(DataQuery query, boolean bSort) {
|
public ItemCollection(DataQuery query, boolean bSort) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007 Chris Gilbert 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.authoring;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
|
import com.arsdigita.cms.ItemSelectionModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class used for decoupled display components that caters
|
||||||
|
* for a callback to provide them with a handle on the ItemSelectionModel
|
||||||
|
* @author chris.gilbert@westsussex.gov.uk
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface AdditionalDisplayComponent extends Component {
|
||||||
|
|
||||||
|
public void setItemSelectionModel (ItemSelectionModel model);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.cms.ui.authoring;
|
package com.arsdigita.cms.ui.authoring;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
import com.arsdigita.bebop.Page;
|
import com.arsdigita.bebop.Page;
|
||||||
import com.arsdigita.bebop.PageState;
|
import com.arsdigita.bebop.PageState;
|
||||||
import com.arsdigita.bebop.event.ActionEvent;
|
import com.arsdigita.bebop.event.ActionEvent;
|
||||||
|
|
@ -63,6 +68,23 @@ public class SimpleEditStep extends SecurityPropertyEditor
|
||||||
private static final String STREAMLINED = "_streamlined";
|
private static final String STREAMLINED = "_streamlined";
|
||||||
private static final String STREAMLINED_DONE = "1";
|
private static final String STREAMLINED_DONE = "1";
|
||||||
|
|
||||||
|
private static List s_additionalDisplayComponents = new ArrayList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* allow additional display components to be added to all implementations
|
||||||
|
* of SimpleEditStep. This allows shared optional packages such as notes to
|
||||||
|
* display information on the initial authoring page of all content types without
|
||||||
|
* causing dependencies from ccm-cms.
|
||||||
|
*
|
||||||
|
* Any additional components must be added before the edit step is created.
|
||||||
|
* An initialiser is a suitable location
|
||||||
|
*
|
||||||
|
* @param c
|
||||||
|
*/
|
||||||
|
public static void addAdditionalDisplayComponent(AdditionalDisplayComponent c) {
|
||||||
|
s_additionalDisplayComponents.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new SimpleEditStep component
|
* Construct a new SimpleEditStep component
|
||||||
*
|
*
|
||||||
|
|
@ -104,6 +126,15 @@ public class SimpleEditStep extends SecurityPropertyEditor
|
||||||
showDisplayPane(state);
|
showDisplayPane(state);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Iterator it = s_additionalDisplayComponents.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
|
||||||
|
AdditionalDisplayComponent component = (AdditionalDisplayComponent)it.next();
|
||||||
|
component.setItemSelectionModel(itemModel);
|
||||||
|
addDisplayComponent(component);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,12 @@ import com.arsdigita.bebop.SimpleContainer;
|
||||||
import com.arsdigita.bebop.Table;
|
import com.arsdigita.bebop.Table;
|
||||||
import com.arsdigita.bebop.event.ActionEvent;
|
import com.arsdigita.bebop.event.ActionEvent;
|
||||||
import com.arsdigita.bebop.event.ActionListener;
|
import com.arsdigita.bebop.event.ActionListener;
|
||||||
|
import com.arsdigita.bebop.event.ChangeEvent;
|
||||||
|
import com.arsdigita.bebop.event.ChangeListener;
|
||||||
import com.arsdigita.bebop.event.TableActionAdapter;
|
import com.arsdigita.bebop.event.TableActionAdapter;
|
||||||
import com.arsdigita.bebop.event.TableActionEvent;
|
import com.arsdigita.bebop.event.TableActionEvent;
|
||||||
import com.arsdigita.bebop.event.TableActionListener;
|
import com.arsdigita.bebop.event.TableActionListener;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
import com.arsdigita.bebop.table.AbstractTableModelBuilder;
|
import com.arsdigita.bebop.table.AbstractTableModelBuilder;
|
||||||
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
|
import com.arsdigita.bebop.table.DefaultTableCellRenderer;
|
||||||
import com.arsdigita.bebop.table.DefaultTableColumnModel;
|
import com.arsdigita.bebop.table.DefaultTableColumnModel;
|
||||||
|
|
@ -114,21 +117,15 @@ public class FolderBrowser extends Table {
|
||||||
private final static String SORT_KEY_LAST_MODIFIED_DATE = "lastModified";
|
private final static String SORT_KEY_LAST_MODIFIED_DATE = "lastModified";
|
||||||
private final static String SORT_KEY_CREATION_DATE = "creationDate";
|
private final static String SORT_KEY_CREATION_DATE = "creationDate";
|
||||||
|
|
||||||
private RequestLocal m_sortType = new RequestLocal() {
|
private StringParameter m_sortType = new StringParameter("sortType");
|
||||||
public Object initialValue(PageState state) {
|
private StringParameter m_sortDirection = new StringParameter("sortDirn");
|
||||||
return SORT_KEY_NAME;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final RequestLocal m_sortDirection = new RequestLocal() {
|
|
||||||
public Object initialValue(PageState state) {
|
|
||||||
return SORT_ACTION_UP;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public FolderBrowser(FolderSelectionModel currentFolder) {
|
public FolderBrowser(FolderSelectionModel currentFolder) {
|
||||||
//super(new FolderTableModelBuilder(), s_headers);
|
//super(new FolderTableModelBuilder(), s_headers);
|
||||||
super();
|
super();
|
||||||
|
m_sortType.setDefaultValue(SORT_KEY_NAME);
|
||||||
|
m_sortDirection.setDefaultValue(SORT_ACTION_UP);
|
||||||
|
|
||||||
setModelBuilder(new FolderTableModelBuilder(currentFolder));
|
setModelBuilder(new FolderTableModelBuilder(currentFolder));
|
||||||
setColumnModel(new DefaultTableColumnModel(hideIndexColumn() ? s_noIndexHeaders : s_headers));
|
setColumnModel(new DefaultTableColumnModel(hideIndexColumn() ? s_noIndexHeaders : s_headers));
|
||||||
setHeader(new TableHeader(getColumnModel()));
|
setHeader(new TableHeader(getColumnModel()));
|
||||||
|
|
@ -144,7 +141,25 @@ public class FolderBrowser extends Table {
|
||||||
((FolderTableModelBuilder)getModelBuilder()).setFolderBrowser(this);
|
((FolderTableModelBuilder)getModelBuilder()).setFolderBrowser(this);
|
||||||
|
|
||||||
m_currentFolder = currentFolder;
|
m_currentFolder = currentFolder;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This code should be uncommented if the desired behaviour is for a change
|
||||||
|
of folder to cause reversion to default ordering of contained items
|
||||||
|
(by name ascending). Our feeling is that the user selected ordering
|
||||||
|
should be retained for the duration of the folder browsing session. If
|
||||||
|
anyone wants this alternative behaviour it should be brought in under
|
||||||
|
the control of a config parameter.
|
||||||
|
|
||||||
|
m_currentFolder.addChangeListener(new ChangeListener() {
|
||||||
|
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
PageState state = e.getPageState();
|
||||||
|
state.setValue(m_sortType, m_sortType.getDefaultValue());
|
||||||
|
state.setValue(m_sortDirection, m_sortDirection.getDefaultValue());
|
||||||
|
|
||||||
|
}});
|
||||||
|
*/
|
||||||
setClassAttr("dataTable");
|
setClassAttr("dataTable");
|
||||||
|
|
||||||
getHeader().setDefaultRenderer(new com.arsdigita.cms.ui.util.DefaultTableCellRenderer());
|
getHeader().setDefaultRenderer(new com.arsdigita.cms.ui.util.DefaultTableCellRenderer());
|
||||||
|
|
@ -182,7 +197,8 @@ public class FolderBrowser extends Table {
|
||||||
super.register(p);
|
super.register(p);
|
||||||
|
|
||||||
p.addComponentStateParam(this, m_currentFolder.getStateParameter());
|
p.addComponentStateParam(this, m_currentFolder.getStateParameter());
|
||||||
|
p.addComponentStateParam(this, m_sortType);
|
||||||
|
p.addComponentStateParam(this, m_sortDirection);
|
||||||
p.addActionListener(new ActionListener() {
|
p.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
final PageState state = e.getPageState();
|
final PageState state = e.getPageState();
|
||||||
|
|
@ -209,11 +225,11 @@ public class FolderBrowser extends Table {
|
||||||
String key = state.getControlEventName();
|
String key = state.getControlEventName();
|
||||||
String value = state.getControlEventValue();
|
String value = state.getControlEventValue();
|
||||||
if ( SORT_ACTION_UP.equals(key) ) {
|
if ( SORT_ACTION_UP.equals(key) ) {
|
||||||
m_sortType.set(state, value);
|
state.setValue(m_sortType, value);
|
||||||
m_sortDirection.set(state, SORT_ACTION_UP);
|
state.setValue(m_sortDirection, SORT_ACTION_UP);
|
||||||
} else if ( SORT_ACTION_DOWN.equals(key) ) {
|
} else if ( SORT_ACTION_DOWN.equals(key) ) {
|
||||||
m_sortType.set(state, value);
|
state.setValue(m_sortType, value);
|
||||||
m_sortDirection.set(state, SORT_ACTION_DOWN);
|
state.setValue(m_sortDirection, SORT_ACTION_DOWN);
|
||||||
} else {
|
} else {
|
||||||
super.respond(state);
|
super.respond(state);
|
||||||
//throw new ServletException("Unknown control event: " + key);
|
//throw new ServletException("Unknown control event: " + key);
|
||||||
|
|
@ -282,9 +298,9 @@ public class FolderBrowser extends Table {
|
||||||
itemColl.setRange(new Integer(paginator.getFirst(state)),
|
itemColl.setRange(new Integer(paginator.getFirst(state)),
|
||||||
new Integer(paginator.getLast(state) + 1));
|
new Integer(paginator.getLast(state) + 1));
|
||||||
|
|
||||||
String sortKey = (String)m_sortType.get(state);
|
String sortKey = (String)state.getValue(m_sortType);
|
||||||
String direction = "asc";
|
String direction = "asc";
|
||||||
if (SORT_ACTION_DOWN.equals((String)m_sortDirection.get(state))) {
|
if (SORT_ACTION_DOWN.equals((String)state.getValue(m_sortDirection))) {
|
||||||
direction = "desc";
|
direction = "desc";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,9 +358,9 @@ public class FolderBrowser extends Table {
|
||||||
boolean isSelected, Object key,
|
boolean isSelected, Object key,
|
||||||
int row, int column) {
|
int row, int column) {
|
||||||
String headerName = (String)((GlobalizedMessage)value).localize();
|
String headerName = (String)((GlobalizedMessage)value).localize();
|
||||||
String sortKey = (String)m_sortType.get(state);
|
String sortKey = (String)state.getValue(m_sortType);
|
||||||
final boolean isCurrentKey = sortKey.equals(m_key);
|
final boolean isCurrentKey = sortKey.equals(m_key);
|
||||||
final String currentSortDirection = (String)m_sortDirection.get(state);
|
final String currentSortDirection = (String)state.getValue(m_sortDirection);
|
||||||
String imageURLStub = null;
|
String imageURLStub = null;
|
||||||
|
|
||||||
if (SORT_ACTION_UP.equals(currentSortDirection)) {
|
if (SORT_ACTION_UP.equals(currentSortDirection)) {
|
||||||
|
|
|
||||||
|
|
@ -452,25 +452,36 @@ class ItemLifecycleSelectForm extends BaseForm {
|
||||||
|
|
||||||
// Apply the new lifecycle.
|
// Apply the new lifecycle.
|
||||||
ContentItem pending = item.publish(cycleDef, startDate);
|
ContentItem pending = item.publish(cycleDef, startDate);
|
||||||
|
final Lifecycle lifecycle = pending.getLifecycle();
|
||||||
|
|
||||||
// XXX domlay Whoa. This must be broken for multiphase
|
// XXX domlay Whoa. This must be broken for multiphase
|
||||||
// lifecycles.
|
// lifecycles.
|
||||||
|
|
||||||
if (endDate != null) {
|
if (endDate != null) {
|
||||||
final Lifecycle lifecycle = pending.getLifecycle();
|
|
||||||
|
|
||||||
// update individual phases
|
// update individual phases
|
||||||
final PhaseCollection phases = lifecycle.getPhases();
|
final PhaseCollection phases = lifecycle.getPhases();
|
||||||
|
|
||||||
while (phases.next()) {
|
while (phases.next()) {
|
||||||
final Phase phase = phases.getPhase();
|
final Phase phase = phases.getPhase();
|
||||||
java.util.Date thisEnd = phase.getEndDate();
|
java.util.Date thisEnd = phase.getEndDate();
|
||||||
|
java.util.Date thisStart = phase.getStartDate();
|
||||||
|
if (thisStart.compareTo(endDate) > 0) {
|
||||||
|
phase.setStartDate(endDate);
|
||||||
|
phase.save();
|
||||||
|
}
|
||||||
|
|
||||||
if (thisEnd == null || thisEnd.compareTo(endDate) > 0) {
|
if (thisEnd == null || thisEnd.compareTo(endDate) > 0) {
|
||||||
phase.setEndDate(endDate);
|
phase.setEndDate(endDate);
|
||||||
phase.save();
|
phase.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endOfCycle may be the original date according to lifecycle phase definitions, or endDate if that was before
|
||||||
|
// natural end of lifecycle
|
||||||
|
java.util.Date endOfCycle = lifecycle.getEndDate();
|
||||||
|
if (endOfCycle != null) {
|
||||||
|
|
||||||
// if advance notification is requested (!= 0)
|
// if advance notification is requested (!= 0)
|
||||||
// add another phase at the start of which the user is notified
|
// add another phase at the start of which the user is notified
|
||||||
|
|
@ -487,15 +498,15 @@ class ItemLifecycleSelectForm extends BaseForm {
|
||||||
if (notificationHours != null) {
|
if (notificationHours != null) {
|
||||||
notificationPeriod += notificationHours.intValue();
|
notificationPeriod += notificationHours.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notificationPeriod > 0) {
|
if (notificationPeriod > 0) {
|
||||||
notificationDate =
|
notificationDate =
|
||||||
computeNotificationDate(endDate, notificationPeriod);
|
computeNotificationDate(endOfCycle, notificationPeriod);
|
||||||
|
s_log.debug("adding custom phase");
|
||||||
Phase expirationImminentPhase =
|
Phase expirationImminentPhase =
|
||||||
lifecycle.addCustomPhase("expirationImminent",
|
lifecycle.addCustomPhase("expirationImminent",
|
||||||
new Long(notificationDate.getTime()),
|
new Long(notificationDate.getTime()),
|
||||||
new Long(endDate.getTime()));
|
new Long(endOfCycle.getTime()));
|
||||||
expirationImminentPhase.
|
expirationImminentPhase.
|
||||||
setListenerClassName("com.arsdigita.cms.lifecycle.NotifyLifecycleListener");
|
setListenerClassName("com.arsdigita.cms.lifecycle.NotifyLifecycleListener");
|
||||||
expirationImminentPhase.save();
|
expirationImminentPhase.save();
|
||||||
|
|
@ -510,7 +521,7 @@ class ItemLifecycleSelectForm extends BaseForm {
|
||||||
item.save();
|
item.save();
|
||||||
|
|
||||||
final Workflow workflow = m_workflow.getWorkflow(state);
|
final Workflow workflow = m_workflow.getWorkflow(state);
|
||||||
try {
|
try {
|
||||||
finish(workflow, item, Web.getContext().getUser());
|
finish(workflow, item, Web.getContext().getUser());
|
||||||
} catch (TaskException te) {
|
} catch (TaskException te) {
|
||||||
throw new FormProcessException(te);
|
throw new FormProcessException(te);
|
||||||
|
|
@ -524,7 +535,7 @@ class ItemLifecycleSelectForm extends BaseForm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finish(Workflow workflow, ContentItem item, User user) throws TaskException {
|
static void finish(Workflow workflow, ContentItem item, User user) throws TaskException {
|
||||||
if (workflow != null) {
|
if (workflow != null) {
|
||||||
final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE);
|
final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE);
|
||||||
|
|
|
||||||
|
|
@ -255,13 +255,15 @@ public class CMSTask extends UserTask {
|
||||||
Assert.assertNotNull(item, "item associated with this CMSTask");
|
Assert.assertNotNull(item, "item associated with this CMSTask");
|
||||||
|
|
||||||
String authoringURL = getAuthoringURL(item);
|
String authoringURL = getAuthoringURL(item);
|
||||||
String fullURL = URL.there(getTaskType().getURLGenerator(operation).generateURL(item.getID(), getID()), null).getURL();
|
String fullURL = getTaskType().getURLGenerator(operation, item).generateURL(item.getID(), getID());
|
||||||
|
s_log.debug("URL retrieved from generator: " + fullURL);
|
||||||
|
if (!fullURL.startsWith("http")) {
|
||||||
|
// url is not fully qualified
|
||||||
|
fullURL = URL.there(fullURL, null).getURL();
|
||||||
|
|
||||||
|
}
|
||||||
// see CMSResources.properties for how these values are used
|
// see CMSResources.properties for how these values are used
|
||||||
Object[] g11nArgs = new Object[10];
|
Object[] g11nArgs = new Object[11];
|
||||||
// cg - make this configurable. Because our content section managers have access to all
|
|
||||||
// folders, they get all notifications, but they want to know which area it relates to -
|
|
||||||
// first folder in item path tells them. config parameter - full item path or just display name
|
|
||||||
// g11nArgs[0] =((ContentItem)item.getParent()).getPath();
|
|
||||||
g11nArgs[0] = item.getDisplayName();
|
g11nArgs[0] = item.getDisplayName();
|
||||||
g11nArgs[1] = new Double(getTaskType().getID().doubleValue());
|
g11nArgs[1] = new Double(getTaskType().getID().doubleValue());
|
||||||
g11nArgs[2] = fullURL;
|
g11nArgs[2] = fullURL;
|
||||||
|
|
@ -283,7 +285,9 @@ public class CMSTask extends UserTask {
|
||||||
}
|
}
|
||||||
g11nArgs[8] = getStartDate();
|
g11nArgs[8] = getStartDate();
|
||||||
g11nArgs[9] = URL.there(authoringURL, null).getURL();
|
g11nArgs[9] = URL.there(authoringURL, null).getURL();
|
||||||
|
//if added to email, allows recipient to identify if the item is in a folder
|
||||||
|
// they are interested in
|
||||||
|
g11nArgs[10] = ((ContentItem)item.getParent()).getPath();
|
||||||
String subject = (String) GlobalizationUtil.globalize("cms.ui.workflow.email.subject." + operation,
|
String subject = (String) GlobalizationUtil.globalize("cms.ui.workflow.email.subject." + operation,
|
||||||
g11nArgs).localize();
|
g11nArgs).localize();
|
||||||
String body = (String) GlobalizationUtil.globalize("cms.ui.workflow.email.body." + operation,
|
String body = (String) GlobalizationUtil.globalize("cms.ui.workflow.email.body." + operation,
|
||||||
|
|
@ -481,8 +485,10 @@ public class CMSTask extends UserTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// bugfix - if author is null above then we break out
|
||||||
|
// of loop early. If normal exit and so cursor has already closed then the
|
||||||
|
// next line has no effect
|
||||||
hist.close();
|
hist.close();
|
||||||
//hist.close here if not closed
|
|
||||||
if (author == null) {
|
if (author == null) {
|
||||||
// fallback: creator is always available in audit trail
|
// fallback: creator is always available in audit trail
|
||||||
author = item.getCreationUser();
|
author = item.getCreationUser();
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ package com.arsdigita.cms.workflow;
|
||||||
|
|
||||||
import com.arsdigita.cms.ContentItem;
|
import com.arsdigita.cms.ContentItem;
|
||||||
import com.arsdigita.cms.ContentSection;
|
import com.arsdigita.cms.ContentSection;
|
||||||
|
import com.arsdigita.cms.ContentType;
|
||||||
import com.arsdigita.cms.SecurityManager;
|
import com.arsdigita.cms.SecurityManager;
|
||||||
import com.arsdigita.cms.ui.ContentItemPage;
|
import com.arsdigita.cms.ui.ContentItemPage;
|
||||||
import com.arsdigita.cms.util.GlobalizationUtil;
|
import com.arsdigita.cms.util.GlobalizationUtil;
|
||||||
|
|
@ -168,23 +169,36 @@ public class CMSTaskType extends DomainObject {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskURLGenerator getURLGenerator(String event) {
|
public TaskURLGenerator getURLGenerator(String event, ContentItem item) {
|
||||||
String key = getID() + " " + event;
|
String key = getID() + " " + event + " " + item.getContentType().getID();
|
||||||
s_log.debug("looking up url generator for key " + key);
|
s_log.debug("looking up url generator for key " + key);
|
||||||
TaskURLGenerator generator = (TaskURLGenerator)
|
TaskURLGenerator generator = (TaskURLGenerator)
|
||||||
s_taskURLGeneratorCache.get(key);
|
s_taskURLGeneratorCache.get(key);
|
||||||
if (generator == null) {
|
if (generator == null) {
|
||||||
s_log.debug("generator not found in cache");
|
s_log.debug("no generator found in cache");
|
||||||
DataAssociationCursor generators = ((DataAssociation)get(URL_GENERATORS)).cursor();
|
DataAssociationCursor generators = ((DataAssociation)get(URL_GENERATORS)).cursor();
|
||||||
generators.addEqualsFilter(TaskEventURLGenerator.EVENT, event);
|
generators.addEqualsFilter(TaskEventURLGenerator.EVENT, event);
|
||||||
|
generators.addEqualsFilter(TaskEventURLGenerator.CONTENT_TYPE + "." + ContentType.ID, item.getContentType().getID());
|
||||||
try {
|
try {
|
||||||
|
|
||||||
while (generators.next()) {
|
while (generators.next()) {
|
||||||
s_log.debug("specific generator found for " + event + " event on task type " + getName());
|
s_log.debug("specific generator found for " + event + " event on task type " + getName() + " for content type " + item.getContentType().getLabel());
|
||||||
|
// generator class available for this specific event and this specific content type
|
||||||
|
generator = ((TaskEventURLGenerator)DomainObjectFactory.newInstance(generators.getDataObject())).getGenerator();
|
||||||
|
generators.close();
|
||||||
|
}
|
||||||
|
if (generator == null) {
|
||||||
|
generators.reset();
|
||||||
|
generators.addEqualsFilter(TaskEventURLGenerator.EVENT, event);
|
||||||
|
generators.addEqualsFilter(TaskEventURLGenerator.CONTENT_TYPE, null);
|
||||||
|
while (generators.next()) {
|
||||||
|
s_log.debug("specific generator found for " + event + " event on task type " + getName() + " for any content type");
|
||||||
// generator class available for this specific event
|
// generator class available for this specific event
|
||||||
generator = ((TaskEventURLGenerator)DomainObjectFactory.newInstance(generators.getDataObject())).getGenerator();
|
generator = ((TaskEventURLGenerator)DomainObjectFactory.newInstance(generators.getDataObject())).getGenerator();
|
||||||
generators.close();
|
generators.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (generator == null) {
|
if (generator == null) {
|
||||||
|
|
||||||
s_log.debug("no specific generator for " + event + " event on task type " + getName()+ ". Revert to default");
|
s_log.debug("no specific generator for " + event + " event on task type " + getName()+ ". Revert to default");
|
||||||
|
|
|
||||||
|
|
@ -18,51 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.cms.workflow;
|
package com.arsdigita.cms.workflow;
|
||||||
|
|
||||||
import com.arsdigita.cms.ContentItem;
|
import org.apache.log4j.Logger;
|
||||||
import com.arsdigita.cms.ContentSection;
|
|
||||||
import com.arsdigita.cms.SecurityManager;
|
|
||||||
import com.arsdigita.cms.ui.ContentItemPage;
|
|
||||||
import com.arsdigita.cms.util.GlobalizationUtil;
|
|
||||||
import com.arsdigita.domain.DataObjectNotFoundException;
|
|
||||||
import com.arsdigita.domain.DomainObject;
|
import com.arsdigita.domain.DomainObject;
|
||||||
import com.arsdigita.domain.DomainObjectFactory;
|
import com.arsdigita.domain.DomainObjectFactory;
|
||||||
import com.arsdigita.kernel.Group;
|
|
||||||
import com.arsdigita.kernel.KernelHelper;
|
|
||||||
import com.arsdigita.kernel.Party;
|
|
||||||
import com.arsdigita.kernel.User;
|
|
||||||
import com.arsdigita.kernel.UserCollection;
|
|
||||||
import com.arsdigita.kernel.permissions.PermissionService;
|
|
||||||
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
|
|
||||||
import com.arsdigita.messaging.Message;
|
|
||||||
import com.arsdigita.notification.Notification;
|
|
||||||
import com.arsdigita.persistence.DataAssociation;
|
|
||||||
import com.arsdigita.persistence.DataAssociationCursor;
|
|
||||||
import com.arsdigita.persistence.DataCollection;
|
import com.arsdigita.persistence.DataCollection;
|
||||||
import com.arsdigita.persistence.DataObject;
|
import com.arsdigita.persistence.DataObject;
|
||||||
import com.arsdigita.persistence.DataOperation;
|
|
||||||
import com.arsdigita.persistence.DataQuery;
|
|
||||||
import com.arsdigita.persistence.Filter;
|
|
||||||
import com.arsdigita.persistence.OID;
|
import com.arsdigita.persistence.OID;
|
||||||
import com.arsdigita.persistence.Session;
|
|
||||||
import com.arsdigita.persistence.SessionManager;
|
import com.arsdigita.persistence.SessionManager;
|
||||||
import com.arsdigita.persistence.metadata.ObjectType;
|
|
||||||
import com.arsdigita.util.Assert;
|
|
||||||
import com.arsdigita.versioning.TagCollection;
|
|
||||||
import com.arsdigita.versioning.Transaction;
|
|
||||||
import com.arsdigita.versioning.TransactionCollection;
|
|
||||||
import com.arsdigita.versioning.Versions;
|
|
||||||
import com.arsdigita.web.URL;
|
|
||||||
import com.arsdigita.workflow.simple.TaskComment;
|
|
||||||
import com.arsdigita.workflow.simple.TaskException;
|
|
||||||
import com.arsdigita.workflow.simple.UserTask;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents enables fine grained control of the url that is
|
* This class represents enables fine grained control of the url that is
|
||||||
|
|
@ -87,6 +50,7 @@ public class TaskEventURLGenerator extends DomainObject {
|
||||||
public static final String EVENT = "event";
|
public static final String EVENT = "event";
|
||||||
public static final String URL_GENERATOR_CLASS =
|
public static final String URL_GENERATOR_CLASS =
|
||||||
"urlGeneratorClass";
|
"urlGeneratorClass";
|
||||||
|
public static final String CONTENT_TYPE = "contentType";
|
||||||
|
|
||||||
private static final Logger s_log = Logger.getLogger(TaskEventURLGenerator.class);
|
private static final Logger s_log = Logger.getLogger(TaskEventURLGenerator.class);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import com.arsdigita.bebop.event.FormSectionEvent;
|
||||||
import com.arsdigita.bebop.form.FormErrorDisplay;
|
import com.arsdigita.bebop.form.FormErrorDisplay;
|
||||||
import com.arsdigita.bebop.form.Submit;
|
import com.arsdigita.bebop.form.Submit;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -150,6 +151,7 @@ public class PropertyEditor extends SimpleContainer {
|
||||||
private List m_list;
|
private List m_list;
|
||||||
private PropertyEditorModelBuilder m_builder;
|
private PropertyEditorModelBuilder m_builder;
|
||||||
private RequestLocal m_model;
|
private RequestLocal m_model;
|
||||||
|
private java.util.List m_additionalDisplayComponents = new ArrayList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new, empty <code>PropertyEditor</code>.
|
* Constructs a new, empty <code>PropertyEditor</code>.
|
||||||
|
|
@ -276,6 +278,13 @@ public class PropertyEditor extends SimpleContainer {
|
||||||
return (String)m_list.getSelectedKey(state);
|
return (String)m_list.getSelectedKey(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add an additional component below the list of links
|
||||||
|
* @param c
|
||||||
|
*/
|
||||||
|
public void addDisplayComponent(Component c) {
|
||||||
|
m_additionalDisplayComponents.add(c);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Adds the display component if it has not been added already.
|
* Adds the display component if it has not been added already.
|
||||||
*
|
*
|
||||||
|
|
@ -288,6 +297,10 @@ public class PropertyEditor extends SimpleContainer {
|
||||||
|
|
||||||
m_displayPane.add(c);
|
m_displayPane.add(c);
|
||||||
m_displayPane.add(m_list);
|
m_displayPane.add(m_list);
|
||||||
|
Iterator it = m_additionalDisplayComponents.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
m_displayPane.add((Component)it.next());
|
||||||
|
}
|
||||||
|
|
||||||
m_display = c;
|
m_display = c;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -552,11 +552,11 @@ public class Table extends BlockStylable implements BebopConstants {
|
||||||
* @param p the page that contains this table
|
* @param p the page that contains this table
|
||||||
*/
|
*/
|
||||||
public void register(Page p) {
|
public void register(Page p) {
|
||||||
ParameterModel m = getRowSelectionModel().getStateParameter();
|
ParameterModel m = getRowSelectionModel() == null ? null : getRowSelectionModel().getStateParameter();
|
||||||
if ( m != null ) {
|
if ( m != null ) {
|
||||||
p.addComponentStateParam(this, m);
|
p.addComponentStateParam(this, m);
|
||||||
}
|
}
|
||||||
m = getColumnSelectionModel().getStateParameter();
|
m = getColumnSelectionModel() == null ? null : getColumnSelectionModel().getStateParameter();
|
||||||
if ( m != null ) {
|
if ( m != null ) {
|
||||||
p.addComponentStateParam(this, m);
|
p.addComponentStateParam(this, m);
|
||||||
}
|
}
|
||||||
|
|
@ -601,7 +601,7 @@ public class Table extends BlockStylable implements BebopConstants {
|
||||||
* <code>false</code> otherwise.
|
* <code>false</code> otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isSelectedRow(PageState s, Object rowKey) {
|
public boolean isSelectedRow(PageState s, Object rowKey) {
|
||||||
if ( rowKey == null ) {
|
if ( rowKey == null || getRowSelectionModel() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getRowSelectionModel().isSelected(s)
|
return getRowSelectionModel().isSelected(s)
|
||||||
|
|
@ -619,7 +619,7 @@ public class Table extends BlockStylable implements BebopConstants {
|
||||||
* <code>false</code> otherwise.
|
* <code>false</code> otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isSelectedColumn(PageState s, Object column) {
|
public boolean isSelectedColumn(PageState s, Object column) {
|
||||||
if ( column == null ) {
|
if ( column == null || getColumnSelectionModel() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getColumnSelectionModel().isSelected(s)
|
return getColumnSelectionModel().isSelected(s)
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,9 @@ public class TableHeader extends SimpleComponent {
|
||||||
* @param column the index of the column to test
|
* @param column the index of the column to test
|
||||||
*/
|
*/
|
||||||
protected boolean isSelected(PageState s, Object key, int column) {
|
protected boolean isSelected(PageState s, Object key, int column) {
|
||||||
|
if (getTable().getColumnSelectionModel() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Object sel = getTable()
|
Object sel = getTable()
|
||||||
.getColumnSelectionModel().getSelectedKey(s);
|
.getColumnSelectionModel().getSelectedKey(s);
|
||||||
if(sel == null) {
|
if(sel == null) {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ import com.arsdigita.domain.DataObjectNotFoundException;
|
||||||
import com.arsdigita.kernel.ACSObject;
|
import com.arsdigita.kernel.ACSObject;
|
||||||
import com.arsdigita.kernel.Party;
|
import com.arsdigita.kernel.Party;
|
||||||
import com.arsdigita.messaging.Message;
|
import com.arsdigita.messaging.Message;
|
||||||
|
import com.arsdigita.persistence.DataCollection;
|
||||||
import com.arsdigita.persistence.OID;
|
import com.arsdigita.persistence.OID;
|
||||||
|
import com.arsdigita.persistence.SessionManager;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
@ -468,6 +470,17 @@ public class Notification extends ACSObject implements NotificationConstants {
|
||||||
if (msg == null) {
|
if (msg == null) {
|
||||||
msgDelete = false;
|
msgDelete = false;
|
||||||
}
|
}
|
||||||
|
// find if there are other referring notifications. If so msgdelete = false
|
||||||
|
// so only the last notification tries to delete the message
|
||||||
|
DataCollection notifications = SessionManager.getSession().retrieve(Notification.BASE_DATA_OBJECT_TYPE);
|
||||||
|
notifications.addEqualsFilter(MESSAGE_ID, msg.getID());
|
||||||
|
notifications.addNotEqualsFilter(ID, this.getID());
|
||||||
|
if (notifications.size() > 0) {
|
||||||
|
// other notifications that still refer to the message. Let
|
||||||
|
// the last one out delete the message else foreign key breach
|
||||||
|
// brings down the whole request queue process
|
||||||
|
msgDelete = false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
msg = null;
|
msg = null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue