FolderBrowser

Spalte im FolderBrowser hinzugefügt, die die vorhandenen Sprachvarianten eines Content Items anzeigt und sowohl die primäre Instance makiert (kursiv, class "primaryInstance) als auch den Status der Veröffentlichung (bold, class "live") der Sprachvariante ausgibt. Die hinterlegt Verlinkung führt auf die draft-Variante des Content Items in der angegebenen Sprache.

git-svn-id: https://svn.libreccm.org/ccm/trunk@1439 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2012-01-11 12:28:32 +00:00
parent 2e67f1bd21
commit 39ad6472b0
5 changed files with 188 additions and 95 deletions

View File

@ -408,7 +408,7 @@ public class ContentBundle extends ContentItem {
* @return A <code>Collection</code> of language 2-letter codes in
* which this item is available
*/
public final Collection getLanguages() {
public final Collection<String> getLanguages() {
// XXX For LIVE bundles, there might be several PENDING
// instances with the same language. Maybe we should filter
// these out and return only one?

View File

@ -70,3 +70,4 @@ cms.ui.folder.no_such_item=Item ID supplied does not match an existing Content I
cms.ui.folder.filter.all=All
cms.ui.folder.filter=Filter for work
cms.ui.folder.filter_do=Filter
cms.ui.folder.languages=

View File

@ -66,3 +66,4 @@ cms.ui.folder.remove_asset_link=Entfernen
cms.ui.folder.filter.all=Alle
cms.ui.folder.filter=Nach Begriff filtern
cms.ui.folder.filter_do=Filtern
cms.ui.folder.languages=

View File

@ -65,3 +65,4 @@ cms.ui.folder.item_is_live=est en ligne ; Vous devez le d\u00e9-publier avant de
cms.ui.folder.no_permission_for_item=Vous n'avez pas l'autorisation de supprimer ou de d\u00e9placer
cms.ui.folder.no_such_item=L'identifiant fourni pour l'\u00e9l\u00e9ment ne correspond pas \u00e0 un contenu existant.
cms.ui.folder.filter.all=
cms.ui.folder.languages=

View File

@ -32,8 +32,6 @@ 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.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.TableActionAdapter;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
@ -45,12 +43,7 @@ import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableHeader;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.Folder;
import com.arsdigita.cms.ItemCollection;
import com.arsdigita.cms.*;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.dispatcher.ItemResolver;
import com.arsdigita.cms.dispatcher.Utilities;
@ -68,12 +61,13 @@ import com.arsdigita.util.Assert;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
import java.util.Iterator;
import javax.servlet.ServletException;
/**
* Browse folders and items. If the user clicks on a folder, the folder
* selection model is updated. If the user clicks on any other item, an
* separate item selection model is updated.
* selection model is updated. If the user clicks on any other item, an separate
* item selection model is updated.
*
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @version $Id: FolderBrowser.java 2017 2009-10-04 09:03:45Z pboy $
@ -82,18 +76,22 @@ public class FolderBrowser extends Table {
private static final Logger s_log = Logger.getLogger(FolderBrowser.class);
private static GlobalizedMessage[] s_headers = {
globalize("cms.ui.folder.name"), globalize("cms.ui.folder.title"),
globalize("cms.ui.folder.name"),
globalize("cms.ui.folder.languages"),
globalize("cms.ui.folder.title"),
globalize("cms.ui.folder.type"),
globalize("cms.ui.folder.creation_date"),
globalize("cms.ui.folder.last_modified"), globalize(
"cms.ui.folder.action"),
globalize("cms.ui.folder.last_modified"),
globalize("cms.ui.folder.action"),
globalize("cms.ui.folder.index")};
private static GlobalizedMessage[] s_noIndexHeaders = {
globalize("cms.ui.folder.name"), globalize("cms.ui.folder.title"),
globalize("cms.ui.folder.name"),
globalize("cms.ui.folder.languages"),
globalize("cms.ui.folder.title"),
globalize("cms.ui.folder.type"),
globalize("cms.ui.folder.creation_date"),
globalize("cms.ui.folder.last_modified"), globalize(
"cms.ui.folder.action")};
globalize("cms.ui.folder.last_modified"),
globalize("cms.ui.folder.action")};
private static final String SORT_ACTION_UP = "sortActionUp";
private static final String SORT_ACTION_DOWN = "sortActionDown";
private FolderSelectionModel m_currentFolder;
@ -122,8 +120,8 @@ public class FolderBrowser extends Table {
setModelBuilder(new FolderTableModelBuilder(currentFolder));
setColumnModel(new DefaultTableColumnModel(hideIndexColumn()
? s_noIndexHeaders
: s_headers));
? s_noIndexHeaders
: s_headers));
setHeader(new TableHeader(getColumnModel()));
// DEE 1/18/02: the folder table model builder needs to know about
// 'this' in order to set visibility, but 'this' isn't available
@ -139,22 +137,22 @@ public class FolderBrowser extends Table {
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());
}});
*
* 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");
@ -164,16 +162,17 @@ public class FolderBrowser extends Table {
m_nameColumn = getColumn(0);
m_nameColumn.setCellRenderer(new NameCellRenderer());
m_nameColumn.setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_NAME));
getColumn(1).setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_TITLE));
getColumn(3).setHeaderRenderer(new HeaderCellRenderer(
SORT_KEY_CREATION_DATE));
getColumn(1).setCellRenderer(new LanguagesCellRenderer());
getColumn(2).setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_TITLE));
getColumn(4).setHeaderRenderer(new HeaderCellRenderer(
SORT_KEY_CREATION_DATE));
getColumn(5).setHeaderRenderer(new HeaderCellRenderer(
SORT_KEY_LAST_MODIFIED_DATE));
m_deleteColumn = getColumn(5);
m_deleteColumn = getColumn(6);
m_deleteColumn.setCellRenderer(new ActionCellRenderer());
m_deleteColumn.setAlign("center");
if (!hideIndexColumn()) {
m_indexColumn = getColumn(6);
m_indexColumn = getColumn(7);
m_indexColumn.setCellRenderer(new IndexToggleRenderer());
m_indexColumn.setAlign("center");
@ -217,7 +216,7 @@ public class FolderBrowser extends Table {
boolean canDelete =
sm.canAccess(state.getRequest(), SecurityManager.DELETE_ITEM,
folder);
folder);
m_deleteColumn.setVisible(state, canDelete);
}
@ -261,7 +260,7 @@ public class FolderBrowser extends Table {
private class FolderTableModelBuilder
extends AbstractTableModelBuilder
implements PaginationModelBuilder,
FolderManipulator.FilterFormModelBuilder {
FolderManipulator.FilterFormModelBuilder {
private FolderSelectionModel m_folder;
private RequestLocal m_size;
@ -273,7 +272,7 @@ public class FolderBrowser extends Table {
}
public FolderTableModelBuilder(FolderSelectionModel sel,
FolderBrowser fb) {
FolderBrowser fb) {
super();
m_folder = sel;
m_size = new RequestLocal();
@ -282,8 +281,7 @@ public class FolderBrowser extends Table {
}
public TableModel makeModel(Table t, PageState s) {
FolderSelectionModel sel = ((FolderBrowser) t).
getFolderSelectionModel();
FolderSelectionModel sel = ((FolderBrowser) t).getFolderSelectionModel();
Folder f = (Folder) sel.getSelectedObject(s);
if (f == null) {
return Table.EMPTY_MODEL;
@ -291,7 +289,7 @@ public class FolderBrowser extends Table {
t.getRowSelectionModel().clearSelection(s);
s_log.debug(String.format("filter = '%s'", s.getValue(m_filter)));
Folder.ItemCollection itemColl =
(Folder.ItemCollection) m_itemColl.get(s);
(Folder.ItemCollection) m_itemColl.get(s);
s_log.debug(String.format("itemColl.size = %d", itemColl.size()));
m_folderSize = itemColl.size();
@ -363,7 +361,7 @@ public class FolderBrowser extends Table {
size = new Integer((int) itemColl.size());
itemColl.setRange(new Integer(paginator.getFirst(state)),
new Integer(paginator.getLast(state) + 1));
new Integer(paginator.getLast(state) + 1));
String sortKey = (String) state.getValue(m_sortType);
String direction = "asc";
@ -374,13 +372,13 @@ public class FolderBrowser extends Table {
if (sortKey.equals(SORT_KEY_TITLE)) {
itemColl.setOrder("lower(item." + ContentItem.DISPLAY_NAME
+ ") " + direction);
+ ") " + direction);
} else if (sortKey.equals(SORT_KEY_NAME)) {
itemColl.setOrder("lower(item." + ContentItem.NAME + ") "
+ direction);
+ direction);
} else if (sortKey.equals(SORT_KEY_LAST_MODIFIED_DATE)) {
itemColl.setOrder("item.auditing.lastModifiedDate "
+ direction);
+ direction);
} else if (sortKey.equals(SORT_KEY_CREATION_DATE)) {
itemColl.setOrder("item.auditing.creationDate " + direction);
}
@ -397,11 +395,11 @@ public class FolderBrowser extends Table {
}
/**
* Indicates whether the paginator should be visible,
* based on the visibility of the folder browser itself.
* Indicates whether the paginator should be visible, based on the
* visibility of the folder browser itself.
*
* @return true if folder browser is visible, or if the
* associated folder browser is unknown.
* @return true if folder browser is visible, or if the associated
* folder browser is unknown.
*/
public boolean isVisible(PageState state) {
return (m_fb != null) ? m_fb.isVisible(state) : true;
@ -419,9 +417,9 @@ public class FolderBrowser extends Table {
}
public Component getComponent(final Table table, final PageState state,
Object value,
boolean isSelected, Object key,
int row, int column) {
Object value,
boolean isSelected, Object key,
int row, int column) {
String headerName = (String) ((GlobalizedMessage) value).localize();
String sortKey = (String) state.getValue(m_sortType);
final boolean isCurrentKey = sortKey.equals(m_key);
@ -442,14 +440,14 @@ public class FolderBrowser extends Table {
// by default, everything sorts "up" unless it
// is the current key and it is already pointing up
if (SORT_ACTION_UP.equals(currentSortDirection)
&& isCurrentKey) {
&& isCurrentKey) {
sortDirectionAction = SORT_ACTION_DOWN;
} else {
sortDirectionAction = SORT_ACTION_UP;
}
ps.setControlEvent(table,
sortDirectionAction,
m_key);
sortDirectionAction,
m_key);
}
};
Label l = new Label();
@ -470,8 +468,8 @@ public class FolderBrowser extends Table {
}
/**
* Produce links to view an item or control links for folders
* to change into the folder.
* Produce links to view an item or control links for folders to change into
* the folder.
*/
private class NameCellRenderer extends DefaultTableCellRenderer {
@ -481,14 +479,14 @@ public class FolderBrowser extends Table {
@Override
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
boolean isSelected, Object key,
int row, int column) {
Folder.ItemCollection coll = (Folder.ItemCollection) value;
String name = coll.getName();
if (coll.isFolder()) {
return super.getComponent(table, state, name,
isSelected, key, row, column);
isSelected, key, row, column);
} else {
ContentSection section = CMS.getContext().getContentSection();
BigDecimal id = coll.getID();
@ -498,9 +496,101 @@ public class FolderBrowser extends Table {
} else {
ItemResolver resolver = section.getItemResolver();
return new Link(name, resolver.generateItemURL(state, id,
name, section,
coll.
getVersion()));
name, section, coll.getVersion()));
}
}
}
}
/**
* Added by: Sören Bernstein <sbernstein@zes.uni-bremen.de>
*
* Produce links to view an item in a specific language and show all
* existing language version and the live status in the folder browser.
*/
private class LanguagesCellRenderer extends DefaultTableCellRenderer {
public LanguagesCellRenderer() {
super(true);
}
@Override
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
Folder.ItemCollection coll = (Folder.ItemCollection) value;
String name = coll.getName();
if (coll.isFolder()) {
// Nothing to show on folders
return new Label();
} else {
ContentPage cp;
try {
cp = new ContentPage(coll.getID());
} catch (DataObjectNotFoundException ex) {
// Content item was not found, return nothing
return new Label();
}
ContentBundle bundle = cp.getContentBundle();
ContentSection section = CMS.getContext().getContentSection();
if (bundle != null
&& !(cp instanceof LanguageInvariantContentItem
&& ((LanguageInvariantContentItem) cp).isLanguageInvariant())) {
Iterator<String> languages = bundle.getLanguages().iterator();
StringBuilder temp = new StringBuilder(20);
SimpleContainer container = new SimpleContainer();
while (languages.hasNext()) {
String lang = languages.next();
ContentItem ci = bundle.getInstance(lang, false);
StringBuilder fontWeight = new StringBuilder(2);
StringBuilder classes = new StringBuilder(20);
if (ci.isLive()) {
fontWeight.append(Label.BOLD);
classes.append("live ");
}
if (bundle.getPrimaryInstance().equals(ci)) {
fontWeight.append(Label.ITALIC);
classes.append("primaryInstance");
}
Label langLabel = new Label(lang);
langLabel.setFontWeight(fontWeight.toString().trim());
langLabel.setClassAttr(classes.toString().trim());
if (section == null) {
container.add(langLabel);
} else {
ItemResolver resolver = section.getItemResolver();
container.add(
new Link(langLabel,
resolver.generateItemURL(state,
ci.getID(),
name,
section,
coll.getVersion())));
}
if (languages.hasNext()) {
container.add(new Label("&nbsp;", false));
}
}
return container;
} else {
return new Label();
}
}
}
@ -527,8 +617,8 @@ public class FolderBrowser extends Table {
}
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
boolean isSelected, Object key,
int row, int column) {
if (((Boolean) value).booleanValue()) {
return s_link;
} else {
@ -540,8 +630,8 @@ public class FolderBrowser extends Table {
private final class IndexToggleRenderer implements TableCellRenderer {
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key, int row,
int column) {
boolean isSelected, Object key, int row,
int column) {
if (value == null) {
return new Label(GlobalizationUtil.globalize("cms.ui.folder.na"));
@ -558,7 +648,7 @@ public class FolderBrowser extends Table {
}
}
// Deletes an item
// Deletes an item
private class ItemDeleter extends TableActionAdapter {
public void cellSelected(TableActionEvent e) {
@ -596,12 +686,13 @@ public class FolderBrowser extends Table {
private static class FolderTableModel implements TableModel {
private static final int NAME = 0;
private static final int TITLE = 1;
private static final int TYPE = 2;
private static final int CREATION_DATE = 3;
private static final int LAST_MODIFIED = 4;
private static final int DELETABLE = 5;
private static final int IS_INDEX = 6;
private static final int LANGUAGES = 1;
private static final int TITLE = 2;
private static final int TYPE = 3;
private static final int CREATION_DATE = 4;
private static final int LAST_MODIFIED = 5;
private static final int DELETABLE = 6;
private static final int IS_INDEX = 7;
private PageState m_state;
private FolderBrowser m_table;
private Folder.ItemCollection m_itemColl;
@ -613,7 +704,7 @@ public class FolderBrowser extends Table {
//m_itemColl = folder.getItems();
//}
public FolderTableModel(FolderBrowser table, PageState state,
Folder.ItemCollection itemColl) {
Folder.ItemCollection itemColl) {
m_state = state;
m_table = table;
m_itemColl = itemColl;
@ -631,7 +722,7 @@ public class FolderBrowser extends Table {
}
public int getColumnCount() {
return hideIndexColumn() ? 6 : 7;
return hideIndexColumn() ? 7 : 8;
}
public boolean nextRow() {
@ -642,6 +733,8 @@ public class FolderBrowser extends Table {
switch (columnIndex) {
case NAME:
return m_itemColl;
case LANGUAGES:
return m_itemColl;
case TITLE:
return m_itemColl.getDisplayName();
case TYPE:
@ -655,7 +748,7 @@ public class FolderBrowser extends Table {
}
case LAST_MODIFIED: {
java.util.Date lastModified =
m_itemColl.getLastModifiedDate();
m_itemColl.getLastModifiedDate();
if (lastModified == null) {
return "--";
}
@ -675,13 +768,12 @@ public class FolderBrowser extends Table {
if (m_folIndexID == null) {
return new Boolean(false);
}
return new Boolean(m_folIndexID.compareTo(m_itemColl.
getBundleID()) == 0);
return new Boolean(m_folIndexID.compareTo(m_itemColl.getBundleID()) == 0);
}
default:
throw new IndexOutOfBoundsException("Column index "
+ columnIndex
+ " not in table model.");
+ columnIndex
+ " not in table model.");
}
}
@ -702,13 +794,13 @@ public class FolderBrowser extends Table {
if (!m_itemColl.hasChildren()) {
if (s_log.isDebugEnabled()) {
s_log.debug("The item is an empty folder; it may be "
+ "deleted");
+ "deleted");
}
return true;
} else {
if (s_log.isDebugEnabled()) {
s_log.debug("The folder is not empty; it cannot be "
+ "deleted");
+ "deleted");
}
return false;
}
@ -724,7 +816,7 @@ public class FolderBrowser extends Table {
public Object getKeyAt(int columnIndex) {
// Mark folders by using their negative ID (dirty, dirty)
return (m_itemColl.isFolder()) ? m_itemColl.getID().negate()
: m_itemColl.getBundleID();
: m_itemColl.getBundleID();
}
}
@ -767,11 +859,10 @@ public class FolderBrowser extends Table {
Folder folder = (Folder) m_fol.getSelectedObject(state);
ContentBundle currentIndexItem = (ContentBundle) folder.
getIndexItem();
ContentBundle currentIndexItem = (ContentBundle) folder.getIndexItem();
if (currentIndexItem == null || (currentIndexItem.getID().
compareTo(contentItem.getID())
!= 0)) {
compareTo(contentItem.getID())
!= 0)) {
folder.setIndexItem(contentItem);
} else {
folder.removeIndexItem();
@ -786,8 +877,7 @@ public class FolderBrowser extends Table {
/**
* Getting the GlobalizedMessage using a CMS Class targetBundle.
*
* @param key The resource key
* @pre ( key != null )
* @param key The resource key @pre ( key != null )
*/
private static GlobalizedMessage globalize(String key) {
return FolderManipulator.globalize(key);