Adds all missing classes for category ui
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4508 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: 4556aac1d5
pull/2/head
parent
4c7b949cec
commit
5be80fd428
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2001-2004 Red Hat Inc. 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.kernel.ui.ACSObjectSelectionModel;
|
||||||
|
import com.arsdigita.toolbox.ui.SecurityContainer;
|
||||||
|
import org.libreccm.security.Party;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container that wraps category admin access checks around UI components.
|
||||||
|
*
|
||||||
|
* @author Michael Pih (pihman@arsdigita.com)
|
||||||
|
* @version $Revision: #9 $ $DateTime: 2004/08/17 23:15:09 $
|
||||||
|
* @version $Id: CategoryAdminContainer.java 2090 2010-04-17 08:04:14Z pboy $
|
||||||
|
*/
|
||||||
|
public class CategoryAdminContainer extends SecurityContainer {
|
||||||
|
|
||||||
|
private ACSObjectSelectionModel m_object;
|
||||||
|
private PrivilegeDescriptor m_priv;
|
||||||
|
|
||||||
|
public CategoryAdminContainer(Component c,
|
||||||
|
ACSObjectSelectionModel object,
|
||||||
|
PrivilegeDescriptor priv) {
|
||||||
|
super(c);
|
||||||
|
m_object = object;
|
||||||
|
m_priv = priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canAccess(Party party, PageState state) {
|
||||||
|
return PermissionService.checkPermission(
|
||||||
|
new PermissionDescriptor(
|
||||||
|
m_priv,
|
||||||
|
(ACSObject) m_object.getSelectedObject(state),
|
||||||
|
party));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003-2004 Red Hat Inc. 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
|
import com.arsdigita.bebop.GridPanel;
|
||||||
|
import com.arsdigita.bebop.Label;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.SaveCancelSection;
|
||||||
|
import com.arsdigita.bebop.event.ParameterEvent;
|
||||||
|
import com.arsdigita.bebop.event.ParameterListener;
|
||||||
|
import com.arsdigita.bebop.form.FormErrorDisplay;
|
||||||
|
import com.arsdigita.bebop.form.TextArea;
|
||||||
|
import com.arsdigita.bebop.form.TextField;
|
||||||
|
import com.arsdigita.bebop.parameters.NotNullValidationListener;
|
||||||
|
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
|
||||||
|
import com.arsdigita.categorization.Category;
|
||||||
|
import com.arsdigita.categorization.CategoryCollection;
|
||||||
|
import com.arsdigita.cms.ui.CMSForm;
|
||||||
|
import com.arsdigita.cms.util.GlobalizationUtil;
|
||||||
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A form which creates a new category. Extends the edit form for
|
||||||
|
* convenience.
|
||||||
|
*
|
||||||
|
* @author Michael Pih
|
||||||
|
* @author Stanislav Freidin <sfreidin@redhat.com>
|
||||||
|
* @version $Id: CategoryBaseForm.java 287 2005-02-22 00:29:02Z sskracic $
|
||||||
|
*/
|
||||||
|
class CategoryBaseForm extends CMSForm {
|
||||||
|
private static final Logger s_log =
|
||||||
|
Logger.getLogger(CategoryBaseForm.class);
|
||||||
|
|
||||||
|
final CategoryRequestLocal m_parent;
|
||||||
|
|
||||||
|
final FormErrorDisplay m_errors;
|
||||||
|
final TextField m_title;
|
||||||
|
final TextArea m_description;
|
||||||
|
final SaveCancelSection m_saveCancelSection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
CategoryBaseForm(final String string, final CategoryRequestLocal parent) {
|
||||||
|
super("AddSubcategories");
|
||||||
|
|
||||||
|
m_parent = parent;
|
||||||
|
|
||||||
|
// Form header
|
||||||
|
Label header = new Label(gz("cms.ui.category.add"));
|
||||||
|
add(header, GridPanel.FULL_WIDTH);
|
||||||
|
|
||||||
|
// Form errors
|
||||||
|
m_errors = new FormErrorDisplay(this);
|
||||||
|
add(m_errors, GridPanel.FULL_WIDTH);
|
||||||
|
|
||||||
|
// Name
|
||||||
|
m_title = new TextField(new TrimmedStringParameter("name"));
|
||||||
|
m_title.setSize(30);
|
||||||
|
m_title.setMaxLength(30);
|
||||||
|
m_title.addValidationListener(new NotNullValidationListener());
|
||||||
|
m_title.addValidationListener(new TitleUniqueListener());
|
||||||
|
add(new Label(gz("cms.ui.name")));
|
||||||
|
add(m_title);
|
||||||
|
|
||||||
|
// Description
|
||||||
|
m_description = new TextArea(new TrimmedStringParameter("description"));
|
||||||
|
m_description.setWrap(TextArea.SOFT);
|
||||||
|
m_description.setRows(5);
|
||||||
|
m_description.setCols(40);
|
||||||
|
m_description.addValidationListener(new NotNullValidationListener());
|
||||||
|
add(new Label(gz("cms.ui.description")));
|
||||||
|
add(m_description);
|
||||||
|
|
||||||
|
// Save and cancel buttons
|
||||||
|
m_saveCancelSection = new SaveCancelSection();
|
||||||
|
add(m_saveCancelSection, GridPanel.FULL_WIDTH | GridPanel.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isCancelled(final PageState state) {
|
||||||
|
return m_saveCancelSection.getCancelButton().isSelected(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GlobalizedMessage gz(final String key) {
|
||||||
|
return GlobalizationUtil.globalize(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String lz(final String key) {
|
||||||
|
return (String) gz(key).localize();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TitleUniqueListener implements ParameterListener {
|
||||||
|
public final void validate(final ParameterEvent e)
|
||||||
|
throws FormProcessException {
|
||||||
|
|
||||||
|
final PageState state = e.getPageState();
|
||||||
|
final String title = (String) m_title.getValue(state);
|
||||||
|
|
||||||
|
final Category parent = m_parent.getCategory(state);
|
||||||
|
final CategoryCollection children = parent.getChildren();
|
||||||
|
|
||||||
|
while (children.next()) {
|
||||||
|
final Category child = children.getCategory();
|
||||||
|
|
||||||
|
if (child.getName().equalsIgnoreCase(title)) {
|
||||||
|
throw new FormProcessException
|
||||||
|
(GlobalizationUtil.globalize("cms.ui.category.name_not_unique"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2003-2004 Red Hat Inc. 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
|
import com.arsdigita.toolbox.ui.ComponentAccess;
|
||||||
|
|
||||||
|
|
||||||
|
public class CategoryComponentAccess extends ComponentAccess {
|
||||||
|
// XXX implement me!
|
||||||
|
|
||||||
|
public CategoryComponentAccess(Component c,
|
||||||
|
CategoryRequestLocal category) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2001-2004 Red Hat Inc. 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.category;
|
||||||
|
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.*;
|
||||||
|
import com.arsdigita.bebop.table.TableCellRenderer;
|
||||||
|
import com.arsdigita.categorization.Category;
|
||||||
|
import com.arsdigita.cms.CMS;
|
||||||
|
import com.arsdigita.cms.ContentPage;
|
||||||
|
import com.arsdigita.cms.ContentSection;
|
||||||
|
import com.arsdigita.cms.ContentType;
|
||||||
|
import com.arsdigita.cms.dispatcher.ItemResolver;
|
||||||
|
import com.arsdigita.cms.ui.CMSContainer;
|
||||||
|
import com.arsdigita.cms.util.GlobalizationUtil;
|
||||||
|
import com.arsdigita.domain.DomainObject;
|
||||||
|
import com.arsdigita.domain.DomainObjectFactory;
|
||||||
|
import com.arsdigita.kernel.ACSObject;
|
||||||
|
import com.arsdigita.kernel.Kernel;
|
||||||
|
import com.arsdigita.kernel.User;
|
||||||
|
import com.arsdigita.kernel.ui.ACSObjectSelectionModel;
|
||||||
|
import com.arsdigita.persistence.DataObject;
|
||||||
|
import com.arsdigita.persistence.DataQuery;
|
||||||
|
import com.arsdigita.persistence.OID;
|
||||||
|
import com.arsdigita.toolbox.ui.DataQueryListModelBuilder;
|
||||||
|
import com.arsdigita.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a list of items for the given category
|
||||||
|
*
|
||||||
|
* WARNING: The code to actually list the items is currently a travesty.
|
||||||
|
* It needs to be re-written from scratch, by using custom data queries.
|
||||||
|
* @version $Id: CategoryItemsBrowser.java 2090 2010-04-17 08:04:14Z pboy $
|
||||||
|
*/
|
||||||
|
public class CategoryItemsBrowser extends Grid {
|
||||||
|
|
||||||
|
private static final org.apache.log4j.Logger s_log =
|
||||||
|
org.apache.log4j.Logger.getLogger(CategoryItemsBrowser.class);
|
||||||
|
|
||||||
|
private RequestLocal m_resolver;
|
||||||
|
|
||||||
|
private String m_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new CategoryItemsBrowser
|
||||||
|
* <p>
|
||||||
|
* The {@link SingleSelectionModel} which will provide the
|
||||||
|
* current category
|
||||||
|
*
|
||||||
|
* @param sel the {@link ACSObjectSelectionModel} which will maintain
|
||||||
|
* the current category
|
||||||
|
*
|
||||||
|
* @param numCols the number of columns in the browser
|
||||||
|
*
|
||||||
|
* @param context the context for the retrieved items. Should be
|
||||||
|
* {@link com.arsdigita.cms.ContentItem#DRAFT} or {@link com.arsdigita.cms.ContentItem#LIVE}
|
||||||
|
*/
|
||||||
|
public CategoryItemsBrowser(ACSObjectSelectionModel sel, int numCols,
|
||||||
|
String context) {
|
||||||
|
super(null, numCols);
|
||||||
|
super.setModelBuilder(new CategoryItemModelBuilder(sel));
|
||||||
|
m_context = context;
|
||||||
|
|
||||||
|
setRowSelectionModel(sel);
|
||||||
|
setEmptyView(new Label(GlobalizationUtil.globalize
|
||||||
|
("cms.ui.category.item.none")));
|
||||||
|
|
||||||
|
// Cache the item resolver
|
||||||
|
m_resolver = new RequestLocal() {
|
||||||
|
public Object initialValue(PageState s) {
|
||||||
|
ContentSection section =
|
||||||
|
CMS.getContext().getContentSection();
|
||||||
|
final ItemResolver itemResolver = section.getItemResolver();
|
||||||
|
s_log.warn("Item resolver is" + itemResolver.getClass());
|
||||||
|
return itemResolver;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setDefaultCellRenderer(new ItemSummaryCellRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current context
|
||||||
|
*/
|
||||||
|
public String getContext() {
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context the new context for the items. Should be
|
||||||
|
* {@link com.arsdigita.cms.ContentItem#DRAFT} or {@link com.arsdigita.cms.ContentItem#LIVE}
|
||||||
|
*/
|
||||||
|
public void setContext(String context) {
|
||||||
|
Assert.isUnlocked(this);
|
||||||
|
m_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates through all the children of the given Category
|
||||||
|
*/
|
||||||
|
private class CategoryItemModelBuilder
|
||||||
|
extends DataQueryListModelBuilder {
|
||||||
|
|
||||||
|
private ACSObjectSelectionModel m_sel;
|
||||||
|
|
||||||
|
public CategoryItemModelBuilder(ACSObjectSelectionModel sel) {
|
||||||
|
super(ContentPage.QUERY_PAGE + "." + ACSObject.ID,
|
||||||
|
ContentPage.QUERY_PAGE);
|
||||||
|
m_sel = sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataQuery getDataQuery(PageState s) {
|
||||||
|
Category cat = (Category)m_sel.getSelectedObject(s);
|
||||||
|
|
||||||
|
ContentSection section = CMS.getContext().getContentSection();
|
||||||
|
User user = (User)Kernel.getContext().getParty();
|
||||||
|
OID oid = null;
|
||||||
|
if (user != null) {
|
||||||
|
oid = user.getOID();
|
||||||
|
}
|
||||||
|
// If the category is the root, list all items
|
||||||
|
if(cat == null || (cat.equals(section.getRootCategory()))) {
|
||||||
|
return ContentPage.getPagesInSectionQuery
|
||||||
|
(section, getContext(), oid);
|
||||||
|
} else {
|
||||||
|
return ContentPage.getPagesInSectionQuery
|
||||||
|
(section, getContext(), cat, oid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a ContentItem in preview mode
|
||||||
|
*/
|
||||||
|
private class ItemSummaryCellRenderer
|
||||||
|
implements TableCellRenderer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getComponent(Table table, PageState state, Object value,
|
||||||
|
boolean isSelected, Object key,
|
||||||
|
int row, int column) {
|
||||||
|
|
||||||
|
if(value == null)
|
||||||
|
return new Label(" ", false);
|
||||||
|
|
||||||
|
DomainObject d = DomainObjectFactory.newInstance((DataObject)value);
|
||||||
|
|
||||||
|
Assert.isTrue(d instanceof ContentPage);
|
||||||
|
ContentPage p = (ContentPage)d;
|
||||||
|
|
||||||
|
CMSContainer box = new CMSContainer();
|
||||||
|
Component c;
|
||||||
|
|
||||||
|
ContentSection section =
|
||||||
|
CMS.getContext().getContentSection();
|
||||||
|
|
||||||
|
ItemResolver resolver = (ItemResolver)m_resolver.get(state);
|
||||||
|
|
||||||
|
final String url = resolver.generateItemURL
|
||||||
|
(state, p.getID(), p.getName(), section,
|
||||||
|
resolver.getCurrentContext(state));
|
||||||
|
c = new Link(p.getTitle(), url);
|
||||||
|
|
||||||
|
c.setClassAttr("title");
|
||||||
|
box.add(c);
|
||||||
|
|
||||||
|
String summary = p.getSearchSummary();
|
||||||
|
if(summary != null && summary.length() > 0) {
|
||||||
|
c = new Label(summary);
|
||||||
|
c.setClassAttr("summary");
|
||||||
|
box.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentType t = p.getContentType();
|
||||||
|
if(t != null) {
|
||||||
|
c = new Label(t.getName());
|
||||||
|
} else {
|
||||||
|
c = new Label(GlobalizationUtil.globalize("cms.ui.category.item"));
|
||||||
|
}
|
||||||
|
c.setClassAttr("type");
|
||||||
|
box.add(c);
|
||||||
|
|
||||||
|
box.setClassAttr("itemSummary");
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2001-2004 Red Hat Inc. 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.list.ListModel;
|
||||||
|
import com.arsdigita.categorization.Category;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link ListModel} that iterates over categories via an iterator
|
||||||
|
* @version $Id: CategoryIteratorListModel.java 2090 2010-04-17 08:04:14Z pboy $
|
||||||
|
*/
|
||||||
|
public class CategoryIteratorListModel implements ListModel {
|
||||||
|
|
||||||
|
private Iterator m_iter;
|
||||||
|
private Category m_cat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new <code>CategoryIteratorListModel</code>
|
||||||
|
*
|
||||||
|
* @param iter an {@link Iterator} over all the categories
|
||||||
|
* which this model will supply
|
||||||
|
*/
|
||||||
|
public CategoryIteratorListModel(Iterator iter) {
|
||||||
|
m_iter = iter;
|
||||||
|
m_cat = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean next() {
|
||||||
|
if(m_iter.hasNext()) {
|
||||||
|
m_cat = (Category)m_iter.next();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getElement() {
|
||||||
|
return m_cat.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return m_cat.getID().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Sören Bernstein 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
|
import com.arsdigita.bebop.Label;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.event.FormInitListener;
|
||||||
|
import com.arsdigita.bebop.event.FormProcessListener;
|
||||||
|
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||||
|
import com.arsdigita.bebop.form.Option;
|
||||||
|
import com.arsdigita.categorization.Category;
|
||||||
|
import com.arsdigita.dispatcher.AccessDeniedException;
|
||||||
|
import com.arsdigita.cms.util.GlobalizationUtil;
|
||||||
|
import com.arsdigita.kernel.Kernel;
|
||||||
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a form for creating new localisations for the given category.
|
||||||
|
*
|
||||||
|
* This class is part of the admin GUI of CCM and extends the standard form
|
||||||
|
* in order to present forms for managing the multi-language categories.
|
||||||
|
*
|
||||||
|
* @author Sören Bernstein <quasi@quasiweb.de>
|
||||||
|
* @version $Id: CategoryLocalizationAddForm.java 287 2005-02-22 00:29:02Z sskracic $
|
||||||
|
*/
|
||||||
|
public class CategoryLocalizationAddForm extends CategoryLocalizationForm {
|
||||||
|
|
||||||
|
private static final Logger s_log = Logger.getLogger(CategoryAddForm.class);
|
||||||
|
|
||||||
|
/** Creates a new instance of CategoryLocalizationAddForm */
|
||||||
|
public CategoryLocalizationAddForm(final CategoryRequestLocal category) {
|
||||||
|
|
||||||
|
super("AddCategoryLocalization",
|
||||||
|
gz("cms.ui.category.localization_add"), category);
|
||||||
|
|
||||||
|
addInitListener(new InitListener());
|
||||||
|
addProcessListener(new ProcessListener());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deaktivate this widget, if category is root
|
||||||
|
// public boolean isVisible(PageState state) {
|
||||||
|
// return !m_category.getCategory(state).isRoot();
|
||||||
|
// }
|
||||||
|
private class InitListener implements FormInitListener {
|
||||||
|
|
||||||
|
public final void init(final FormSectionEvent e)
|
||||||
|
throws FormProcessException {
|
||||||
|
|
||||||
|
final PageState state = e.getPageState();
|
||||||
|
final Category category = m_category.getCategory(state);
|
||||||
|
|
||||||
|
// Select one entry
|
||||||
|
m_locale.addOption(new Option("",
|
||||||
|
new Label(GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.select_one"))), state);
|
||||||
|
|
||||||
|
// all supported languages (by registry entry)
|
||||||
|
KernelConfig kernelConfig = Kernel.getConfig();
|
||||||
|
StringTokenizer strTok = kernelConfig.getSupportedLanguagesTokenizer();
|
||||||
|
|
||||||
|
while (strTok.hasMoreTokens()) {
|
||||||
|
|
||||||
|
String code = strTok.nextToken();
|
||||||
|
|
||||||
|
// If lanuage exists, remove it from the selection list
|
||||||
|
if (!category.getCategoryLocalizationCollection().
|
||||||
|
localizationExists(code)) {
|
||||||
|
m_locale.addOption(new Option(code,
|
||||||
|
new Locale(code).getDisplayLanguage()), state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class ProcessListener implements FormProcessListener {
|
||||||
|
|
||||||
|
public final void process(final FormSectionEvent e)
|
||||||
|
throws FormProcessException {
|
||||||
|
s_log.debug("Adding a categoryLocalization to category " + m_category);
|
||||||
|
|
||||||
|
final PageState state = e.getPageState();
|
||||||
|
|
||||||
|
final Category category = m_category.getCategory(state);
|
||||||
|
final String locale = (String) m_locale.getValue(state);
|
||||||
|
final String name = (String) m_name.getValue(state);
|
||||||
|
final String description = (String) m_description.getValue(state);
|
||||||
|
final String url = (String) m_url.getValue(state);
|
||||||
|
final String isEnabled = (String) m_isEnabled.getValue(state);
|
||||||
|
|
||||||
|
// Was soll das??
|
||||||
|
//Assert.assertNotNull(parent, "Category parent");
|
||||||
|
|
||||||
|
if (s_log.isDebugEnabled()) {
|
||||||
|
s_log.debug("Adding localization for locale " + locale
|
||||||
|
+ " to category " + category);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category.canEdit()) {
|
||||||
|
category.addLanguage(locale, name, description, url);
|
||||||
|
category.setEnabled("yes".equals(isEnabled), locale);
|
||||||
|
category.save();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// XXX user a better exception here.
|
||||||
|
// PermissionException doesn't work for this case.
|
||||||
|
throw new AccessDeniedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Sören Bernstein 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.SingleSelectionModel;
|
||||||
|
import com.arsdigita.bebop.event.FormInitListener;
|
||||||
|
import com.arsdigita.bebop.event.FormProcessListener;
|
||||||
|
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||||
|
import com.arsdigita.bebop.form.Option;
|
||||||
|
import com.arsdigita.categorization.Category;
|
||||||
|
import com.arsdigita.dispatcher.AccessDeniedException;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a form for editing an existing localisation for the given category.
|
||||||
|
*
|
||||||
|
* This class is part of the admin GUI of CCM and extends the standard form
|
||||||
|
* in order to present forms for managing the multi-language categories.
|
||||||
|
*
|
||||||
|
* @author Sören Bernstein <quasi@quasiweb.de>
|
||||||
|
* @version $Id: CategoryLocalizationEditForm.java $
|
||||||
|
*/
|
||||||
|
public class CategoryLocalizationEditForm extends CategoryLocalizationForm {
|
||||||
|
|
||||||
|
private static final Logger s_log = Logger.getLogger
|
||||||
|
(CategoryLocalizationEditForm.class);
|
||||||
|
|
||||||
|
private final SingleSelectionModel m_catLocale;
|
||||||
|
/**
|
||||||
|
* Creates a new instance of CategoryLocalizationEditForm
|
||||||
|
*/
|
||||||
|
public CategoryLocalizationEditForm(final CategoryRequestLocal category, SingleSelectionModel catLocale) {
|
||||||
|
|
||||||
|
super("EditCategoryLocalization", gz(
|
||||||
|
"cms.ui.category.localization_edit"), category);
|
||||||
|
|
||||||
|
m_catLocale = catLocale;
|
||||||
|
|
||||||
|
addInitListener(new InitListener());
|
||||||
|
addProcessListener(new ProcessListener());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* please add: purpose of this class
|
||||||
|
*/
|
||||||
|
private class InitListener implements FormInitListener {
|
||||||
|
public final void init(final FormSectionEvent e)
|
||||||
|
throws FormProcessException {
|
||||||
|
|
||||||
|
final PageState state = e.getPageState();
|
||||||
|
final Category category = m_category.getCategory(state);
|
||||||
|
|
||||||
|
final String categoryLocalizationLocale = (String) m_catLocale.getSelectedKey(state);
|
||||||
|
|
||||||
|
// Hide Locale-Widget and lock it (read-only)
|
||||||
|
m_locale.addOption(new Option(categoryLocalizationLocale,
|
||||||
|
new Locale(categoryLocalizationLocale).getDisplayLanguage()), state);
|
||||||
|
m_locale.setValue(state, categoryLocalizationLocale);
|
||||||
|
// m_locale.setVisible(state, false);
|
||||||
|
m_locale.lock();
|
||||||
|
|
||||||
|
m_name.setValue(state, category.getName(categoryLocalizationLocale));
|
||||||
|
m_description.setValue(state, category.getDescription(categoryLocalizationLocale));
|
||||||
|
m_url.setValue(state, category.getURL(categoryLocalizationLocale));
|
||||||
|
|
||||||
|
if (category.isEnabled(categoryLocalizationLocale)) {
|
||||||
|
m_isEnabled.setValue(state, "yes");
|
||||||
|
} else {
|
||||||
|
m_isEnabled.setValue(state, "no");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ##todo: document purpose of this
|
||||||
|
*/
|
||||||
|
private class ProcessListener implements FormProcessListener {
|
||||||
|
public final void process(final FormSectionEvent e)
|
||||||
|
throws FormProcessException {
|
||||||
|
|
||||||
|
final PageState state = e.getPageState();
|
||||||
|
final Category category = m_category.getCategory(state);
|
||||||
|
|
||||||
|
if (s_log.isDebugEnabled()) {
|
||||||
|
s_log.debug("Editing localization for locale " + m_locale +
|
||||||
|
" for category " + category);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category.canEdit()) {
|
||||||
|
category.setName((String) m_name.getValue(state),
|
||||||
|
(String) m_locale.getValue(state));
|
||||||
|
category.setDescription((String) m_description.getValue(state),
|
||||||
|
(String) m_locale.getValue(state));
|
||||||
|
category.setURL((String) m_url.getValue(state),
|
||||||
|
(String) m_locale.getValue(state));
|
||||||
|
category.setEnabled("yes".equals(
|
||||||
|
(String) m_isEnabled.getValue(state)),
|
||||||
|
(String) m_locale.getValue(state));
|
||||||
|
category.save();
|
||||||
|
} else {
|
||||||
|
throw new AccessDeniedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,260 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Sören Bernstein 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Embedded;
|
||||||
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
|
import com.arsdigita.bebop.Label;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.event.ParameterEvent;
|
||||||
|
import com.arsdigita.bebop.event.ParameterListener;
|
||||||
|
import com.arsdigita.bebop.event.PrintEvent;
|
||||||
|
import com.arsdigita.bebop.event.PrintListener;
|
||||||
|
import com.arsdigita.bebop.form.Hidden;
|
||||||
|
import com.arsdigita.bebop.form.Option;
|
||||||
|
import com.arsdigita.bebop.form.RadioGroup;
|
||||||
|
import com.arsdigita.bebop.form.SingleSelect;
|
||||||
|
import com.arsdigita.bebop.form.TextArea;
|
||||||
|
import com.arsdigita.bebop.form.TextField;
|
||||||
|
import com.arsdigita.bebop.form.Widget;
|
||||||
|
import com.arsdigita.bebop.parameters.NotNullValidationListener;
|
||||||
|
import com.arsdigita.bebop.parameters.ParameterData;
|
||||||
|
import com.arsdigita.bebop.parameters.ParameterModel;
|
||||||
|
import com.arsdigita.bebop.parameters.StringInRangeValidationListener;
|
||||||
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
|
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
|
||||||
|
import com.arsdigita.categorization.Category;
|
||||||
|
import com.arsdigita.categorization.CategoryCollection;
|
||||||
|
import com.arsdigita.cms.ui.BaseForm;
|
||||||
|
import com.arsdigita.cms.util.GlobalizationUtil;
|
||||||
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
|
import com.arsdigita.web.Web;
|
||||||
|
import com.arsdigita.xml.Element;
|
||||||
|
import java.util.TooManyListenersException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for CategoryLocalizationAddForm and CategoryLocalizationEditForm.
|
||||||
|
*
|
||||||
|
* This class is part of the admin GUI of CCM and extends the standard form in order to present
|
||||||
|
* forms for managing the multi-language categories.
|
||||||
|
*
|
||||||
|
* @author Sören Bernstein <quasi@quasiweb.de>
|
||||||
|
* @version $Id: $
|
||||||
|
*/
|
||||||
|
public class CategoryLocalizationForm extends BaseForm {
|
||||||
|
|
||||||
|
final CategoryRequestLocal m_category;
|
||||||
|
final SingleSelect m_locale;
|
||||||
|
final TextField m_name;
|
||||||
|
final TextArea m_description;
|
||||||
|
//final TextField m_url;
|
||||||
|
final Hidden m_url;
|
||||||
|
final RadioGroup m_isEnabled;
|
||||||
|
private Embedded m_script = new Embedded(String.format(
|
||||||
|
"<script language=\"javascript\" src=\"%s/javascript/manipulate-input.js\">" + "</script>",
|
||||||
|
Web.getWebappContextPath()),
|
||||||
|
false);
|
||||||
|
|
||||||
|
private final static String LOCALE = "locale";
|
||||||
|
private final static String NAME = "name";
|
||||||
|
private final static String DESCRIPTION = "description";
|
||||||
|
private final static String URL = "url";
|
||||||
|
private final static String IS_ENABLED = "isEnabled";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of CategoryLocalizationForm.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param heading
|
||||||
|
* @param category
|
||||||
|
*/
|
||||||
|
public CategoryLocalizationForm(final String key,
|
||||||
|
final GlobalizedMessage heading,
|
||||||
|
final CategoryRequestLocal category) {
|
||||||
|
|
||||||
|
super(key, heading);
|
||||||
|
|
||||||
|
m_category = category;
|
||||||
|
|
||||||
|
// Parameter-Model for SingleSelect
|
||||||
|
ParameterModel localeParam = new StringParameter(LOCALE);
|
||||||
|
localeParam.addParameterListener(new StringInRangeValidationListener(0, 2));
|
||||||
|
|
||||||
|
m_locale = new SingleSelect(localeParam);
|
||||||
|
m_locale.addValidationListener(new ParameterListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate(ParameterEvent e) throws FormProcessException {
|
||||||
|
|
||||||
|
// the --select one-- option is not allowed
|
||||||
|
ParameterData data = e.getParameterData();
|
||||||
|
String code = (String) data.getValue();
|
||||||
|
if (code == null || code.length() == 0) {
|
||||||
|
data.addError(
|
||||||
|
GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization_error_locale"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
addField(gz("cms.ui.category.localization_locale"), m_locale);
|
||||||
|
|
||||||
|
m_name = new TextField(new TrimmedStringParameter(NAME));
|
||||||
|
addField(gz("cms.ui.name"), m_name);
|
||||||
|
|
||||||
|
m_name.setSize(30);
|
||||||
|
m_name.setMaxLength(200);
|
||||||
|
m_name.addValidationListener(new NotNullValidationListener());
|
||||||
|
m_name.setOnFocus("if (this.form." + URL + ".value == '') { "
|
||||||
|
+ " defaulting = true; this.form." + URL
|
||||||
|
+ ".value = urlize(this.value); }");
|
||||||
|
m_name.setOnKeyUp("if (defaulting) { this.form." + URL + ".value = urlize(this.value) }");
|
||||||
|
|
||||||
|
// is enabled?
|
||||||
|
m_isEnabled = new RadioGroup(IS_ENABLED);
|
||||||
|
m_isEnabled.addOption(new Option("no", new Label(gz("cms.ui.no"))));
|
||||||
|
m_isEnabled.addOption(new Option("yes", new Label(gz("cms.ui.yes"))));
|
||||||
|
addField(gz("cms.ui.category.is_enabled"), m_isEnabled);
|
||||||
|
|
||||||
|
m_description = new TextArea(new TrimmedStringParameter(DESCRIPTION));
|
||||||
|
addField(gz("cms.ui.description"), m_description);
|
||||||
|
|
||||||
|
m_description.setWrap(TextArea.SOFT);
|
||||||
|
m_description.setRows(5);
|
||||||
|
m_description.setCols(40);
|
||||||
|
|
||||||
|
// URL
|
||||||
|
// JavaScript auto-url generation is off by default.
|
||||||
|
// It is turned on under the following circumstances
|
||||||
|
//
|
||||||
|
// * If the url is null, upon starting edit of the title
|
||||||
|
// * If the url is null, upon finishing edit of name
|
||||||
|
//
|
||||||
|
// The rationale is that, auto-url generation is useful
|
||||||
|
// if the url is currently null, but once a name has been
|
||||||
|
// created you don't want to subsequently change it since
|
||||||
|
// it breaks URLs & potentially overwrites the user's
|
||||||
|
// customizations.
|
||||||
|
// m_url = new TextField(new TrimmedStringParameter(URL));
|
||||||
|
// m_url.setSize(30);
|
||||||
|
// m_url.setMaxLength(200);
|
||||||
|
// m_url.addValidationListener(new NotNullValidationListener());
|
||||||
|
// m_url.setOnFocus("defaulting = false");
|
||||||
|
// m_url.setOnBlur("if (this.value == '') "
|
||||||
|
// + "{ defaulting = true; this.value = urlize(this.form." + NAME
|
||||||
|
// + ".value) } " + "else { this.value = urlize(this.value); }");
|
||||||
|
// addField(gz("cms.ui.category.url"), m_url);
|
||||||
|
//jensp 2014-09-16: Localisation of URLs is not useful but causes problems when resolving
|
||||||
|
//the URLs. Also, a category is the same resource for every language variant therefore
|
||||||
|
//the URL should be the same.
|
||||||
|
//Changed field to Hidden, initalised with URL of category itself.
|
||||||
|
m_url = new Hidden(new TrimmedStringParameter(URL));
|
||||||
|
try {
|
||||||
|
m_url.addPrintListener(new PrintListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare(final PrintEvent event) {
|
||||||
|
final Hidden target = (Hidden) event.getTarget();
|
||||||
|
final PageState state = event.getPageState();
|
||||||
|
|
||||||
|
final Category cat = m_category.getCategory(state);
|
||||||
|
|
||||||
|
target.setValue(state, cat.getURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (TooManyListenersException ex) {
|
||||||
|
Logger.getLogger(CategoryLocalizationForm.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
Logger.getLogger(CategoryLocalizationForm.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
addField(gz("cms.ui.category.url"), m_url);
|
||||||
|
|
||||||
|
addAction(new Finish());
|
||||||
|
addAction(new Cancel());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateXML(PageState ps, Element parent) {
|
||||||
|
m_script.generateXML(ps, parent);
|
||||||
|
super.generateXML(ps, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* XXXToDo: Should be extended with the function: Names have to be unambiguous in the selected
|
||||||
|
* language
|
||||||
|
*/
|
||||||
|
class NameUniqueListener implements ParameterListener {
|
||||||
|
|
||||||
|
private final CategoryRequestLocal m_category;
|
||||||
|
private final Widget m_widget;
|
||||||
|
private final int m_type;
|
||||||
|
public final static int NAME_FIELD = 1;
|
||||||
|
public final static int URL_FIELD = 2;
|
||||||
|
|
||||||
|
NameUniqueListener(final CategoryRequestLocal category) {
|
||||||
|
this(category, m_name, NAME_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
NameUniqueListener(final CategoryRequestLocal category,
|
||||||
|
Widget widget, int type) {
|
||||||
|
m_category = category;
|
||||||
|
m_widget = widget;
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purpose:
|
||||||
|
*
|
||||||
|
* XXX provisional, has to be adapted
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*
|
||||||
|
* @throws com.arsdigita.bebop.FormProcessException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void validate(final ParameterEvent e)
|
||||||
|
throws FormProcessException {
|
||||||
|
final PageState state = e.getPageState();
|
||||||
|
final String title = (String) m_widget.getValue(state);
|
||||||
|
|
||||||
|
final Category category = m_category.getCategory(state);
|
||||||
|
|
||||||
|
final CategoryCollection children = category.getChildren();
|
||||||
|
|
||||||
|
while (children.next()) {
|
||||||
|
final Category child = children.getCategory();
|
||||||
|
String compField = (m_type == URL_FIELD) ? child.getURL() : child.getName();
|
||||||
|
if (compField.equalsIgnoreCase(title)
|
||||||
|
&& (m_category == null
|
||||||
|
|| !m_category.getCategory(state).equals(child))) {
|
||||||
|
throw new FormProcessException(GlobalizationUtil.globalize("cms.ui.category.name_not_unique"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Sören Bernstein 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.category;
|
||||||
|
|
||||||
|
import com.arsdigita.bebop.Component;
|
||||||
|
import com.arsdigita.bebop.ControlLink;
|
||||||
|
import com.arsdigita.bebop.Label;
|
||||||
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.SingleSelectionModel;
|
||||||
|
import com.arsdigita.bebop.Table;
|
||||||
|
import com.arsdigita.bebop.event.TableActionEvent;
|
||||||
|
import com.arsdigita.bebop.event.TableActionListener;
|
||||||
|
import com.arsdigita.bebop.table.TableCellRenderer;
|
||||||
|
import com.arsdigita.bebop.table.TableColumn;
|
||||||
|
import com.arsdigita.bebop.table.TableColumnModel;
|
||||||
|
import com.arsdigita.bebop.table.TableModel;
|
||||||
|
import com.arsdigita.bebop.table.TableModelBuilder;
|
||||||
|
import com.arsdigita.categorization.Category;
|
||||||
|
import com.arsdigita.categorization.CategoryLocalization;
|
||||||
|
import com.arsdigita.categorization.CategoryLocalizationCollection;
|
||||||
|
import com.arsdigita.cms.util.GlobalizationUtil;
|
||||||
|
import com.arsdigita.util.LockableImpl;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all existing localizations for a selected category.
|
||||||
|
*
|
||||||
|
* This class is part of the admin GUI of CCM and extends the standard form in
|
||||||
|
* order to present forms for managing the multi-language categories.
|
||||||
|
*
|
||||||
|
* @author Sören Bernstein <quasi@quasiweb.de>
|
||||||
|
*/
|
||||||
|
public class CategoryLocalizationTable extends Table implements TableActionListener {
|
||||||
|
|
||||||
|
private final CategoryRequestLocal m_category;
|
||||||
|
private final SingleSelectionModel m_model;
|
||||||
|
private final String TABLE_COL_LANG = "table_col_lang";
|
||||||
|
private final String TABLE_COL_DEL = "table_col_del";
|
||||||
|
private final SingleSelectionModel m_catLocale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of CategoryLocalizationTable
|
||||||
|
*/
|
||||||
|
public CategoryLocalizationTable(final CategoryRequestLocal category, final SingleSelectionModel model, SingleSelectionModel catLocale) {
|
||||||
|
|
||||||
|
super();
|
||||||
|
|
||||||
|
m_category = category;
|
||||||
|
m_model = model;
|
||||||
|
m_catLocale = catLocale;
|
||||||
|
|
||||||
|
// if table is empty:
|
||||||
|
setEmptyView(new Label(GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization_none")));
|
||||||
|
TableColumnModel tab_model = getColumnModel();
|
||||||
|
|
||||||
|
// define columns
|
||||||
|
// XXX globalize
|
||||||
|
tab_model.add(new TableColumn(0, GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization.locale").localize(), TABLE_COL_LANG));
|
||||||
|
tab_model.add(new TableColumn(1, GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization_name").localize()));
|
||||||
|
tab_model.add(new TableColumn(2, GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization_description").localize()));
|
||||||
|
tab_model.add(new TableColumn(3, GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization_url").localize()));
|
||||||
|
tab_model.add(new TableColumn(4, GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization_action").localize(), TABLE_COL_DEL));
|
||||||
|
|
||||||
|
setModelBuilder(new CategoryLocalizationTableModelBuilder());
|
||||||
|
|
||||||
|
tab_model.get(0).setCellRenderer(new EditCellRenderer());
|
||||||
|
tab_model.get(4).setCellRenderer(new DeleteCellRenderer());
|
||||||
|
|
||||||
|
addTableActionListener(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XXXX
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class CategoryLocalizationTableModelBuilder extends LockableImpl
|
||||||
|
implements TableModelBuilder {
|
||||||
|
|
||||||
|
public TableModel makeModel(Table table, PageState state) {
|
||||||
|
final Category category = m_category.getCategory(state);
|
||||||
|
|
||||||
|
if (category != null && category.hasLocalizations()) {
|
||||||
|
return new CategoryLocalizationTableModel(table, state, category);
|
||||||
|
} else {
|
||||||
|
return Table.EMPTY_MODEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XXX
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class CategoryLocalizationTableModel implements TableModel {
|
||||||
|
|
||||||
|
final private int MAX_DESC_LENGTH = 25;
|
||||||
|
private Table m_table;
|
||||||
|
private CategoryLocalizationCollection m_categoryLocalizations;
|
||||||
|
private CategoryLocalization m_categoryLocalization;
|
||||||
|
|
||||||
|
private CategoryLocalizationTableModel(Table t, PageState ps, Category category) {
|
||||||
|
m_table = t;
|
||||||
|
m_categoryLocalizations = new CategoryLocalizationCollection(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnCount() {
|
||||||
|
return m_table.getColumnModel().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check collection for the existence of another row.
|
||||||
|
*
|
||||||
|
* If exists, fetch the value of current CategoryLocalization object
|
||||||
|
* into m_categoryLocalization class variable.
|
||||||
|
*/
|
||||||
|
public boolean nextRow() {
|
||||||
|
|
||||||
|
if (m_categoryLocalizations != null && m_categoryLocalizations.next()) {
|
||||||
|
m_categoryLocalization = m_categoryLocalizations.getCategoryLocalization();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the
|
||||||
|
*
|
||||||
|
* @see com.arsdigita.bebop.table.TableModel#getElementAt(int)
|
||||||
|
*/
|
||||||
|
public Object getElementAt(int columnIndex) {
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 0:
|
||||||
|
Locale clLocale = new Locale(m_categoryLocalization.getLocale());
|
||||||
|
return clLocale.getDisplayLanguage(/*Locale*/);
|
||||||
|
case 1:
|
||||||
|
return m_categoryLocalization.getName();
|
||||||
|
case 2:
|
||||||
|
String desc = m_categoryLocalization.getDescription();
|
||||||
|
if (desc != null && desc.length() > MAX_DESC_LENGTH) {
|
||||||
|
desc = desc.substring(MAX_DESC_LENGTH - 3).concat("...");
|
||||||
|
}
|
||||||
|
return desc;
|
||||||
|
case 3:
|
||||||
|
return m_categoryLocalization.getURL();
|
||||||
|
case 4:
|
||||||
|
return GlobalizationUtil.globalize("cms.ui.delete").localize();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @see com.arsdigita.bebop.table.TableModel#getKeyAt(int)
|
||||||
|
*/
|
||||||
|
public Object getKeyAt(int columnIndex) {
|
||||||
|
return m_categoryLocalization.getID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EditCellRenderer extends LockableImpl implements TableCellRenderer {
|
||||||
|
|
||||||
|
public Component getComponent(Table table, PageState state, Object value,
|
||||||
|
boolean isSelected, final Object key,
|
||||||
|
int row, int column) {
|
||||||
|
|
||||||
|
|
||||||
|
if (m_category.getCategory(state).canEdit()) {
|
||||||
|
return new ControlLink(value.toString());
|
||||||
|
} else {
|
||||||
|
return new Label(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DeleteCellRenderer extends LockableImpl implements TableCellRenderer {
|
||||||
|
|
||||||
|
public Component getComponent(Table table, PageState state, Object value,
|
||||||
|
boolean isSelected, Object key,
|
||||||
|
int row, int column) {
|
||||||
|
|
||||||
|
if (m_category.getCategory(state).canDelete()) {
|
||||||
|
ControlLink link = new ControlLink(value.toString());
|
||||||
|
link.setConfirmation((String) GlobalizationUtil.globalize(
|
||||||
|
"cms.ui.category.localization_confirm_delete").localize());
|
||||||
|
return link;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide implementation to TableActionListener method. Code that comes
|
||||||
|
* into picture when a link on the table is clicked. Handles edit and delete
|
||||||
|
* event.
|
||||||
|
*/
|
||||||
|
public void cellSelected(TableActionEvent evt) {
|
||||||
|
|
||||||
|
PageState state = evt.getPageState();
|
||||||
|
|
||||||
|
// Get selected CategoryLocalization
|
||||||
|
CategoryLocalization categoryLocalization =
|
||||||
|
new CategoryLocalization(new BigDecimal(evt.getRowKey().toString()));
|
||||||
|
|
||||||
|
// Get Category
|
||||||
|
Category category = m_category.getCategory(state);
|
||||||
|
|
||||||
|
// Get selected column
|
||||||
|
TableColumn col = getColumnModel().get(evt.getColumn().intValue());
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
if (col.getHeaderKey().toString().equals(TABLE_COL_LANG)) {
|
||||||
|
m_catLocale.setSelectedKey(state, categoryLocalization.getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
if (col.getHeaderKey().toString().equals(TABLE_COL_DEL)) {
|
||||||
|
category.delLanguage(categoryLocalization.getLocale());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provide Implementation to TableActionListener method. Does nothing in our
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
public void headSelected(TableActionEvent e) {
|
||||||
|
throw new UnsupportedOperationException("Not Implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue