From a78f8434d3eadb2273eedb9db07ab7ed07be6d4f Mon Sep 17 00:00:00 2001 From: baka Date: Thu, 5 Jan 2017 14:28:14 +0000 Subject: [PATCH] Adds all missing classes for category ui git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4508 8810af33-2d31-482b-a856-94f89814c4df --- .../category/CategoryAdminContainer.java.off | 55 ++++ .../cms/ui/category/CategoryBaseForm.java.off | 131 +++++++++ .../ui/category/CategoryComponentAccess.java | 32 +++ .../ui/category/CategoryItemsBrowser.java.off | 204 ++++++++++++++ .../CategoryIteratorListModel.java.off | 62 +++++ .../CategoryLocalizationAddForm.java.off | 132 +++++++++ .../CategoryLocalizationEditForm.java.off | 126 +++++++++ .../CategoryLocalizationForm.java.off | 260 ++++++++++++++++++ .../CategoryLocalizationTable.java.off | 259 +++++++++++++++++ 9 files changed, 1261 insertions(+) create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminContainer.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryBaseForm.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryComponentAccess.java create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryItemsBrowser.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryIteratorListModel.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java.off diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminContainer.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminContainer.java.off new file mode 100755 index 000000000..5f6bb4321 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryAdminContainer.java.off @@ -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)); + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryBaseForm.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryBaseForm.java.off new file mode 100755 index 000000000..fc7a4b60b --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryBaseForm.java.off @@ -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")); + } + } + } + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryComponentAccess.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryComponentAccess.java new file mode 100755 index 000000000..355a8c09a --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryComponentAccess.java @@ -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); + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryItemsBrowser.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryItemsBrowser.java.off new file mode 100755 index 000000000..00ac15e07 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryItemsBrowser.java.off @@ -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 + *

+ * 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; + } + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryIteratorListModel.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryIteratorListModel.java.off new file mode 100755 index 000000000..78cd53137 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryIteratorListModel.java.off @@ -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 CategoryIteratorListModel + * + * @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(); + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java.off new file mode 100755 index 000000000..21199feff --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java.off @@ -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 + * @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(); + } + } + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java.off new file mode 100755 index 000000000..08114e879 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java.off @@ -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 + * @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(); + } + } + } +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java.off new file mode 100755 index 000000000..69de7d718 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java.off @@ -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 + * @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( + "", + 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")); + } + } + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java.off new file mode 100755 index 000000000..5f37527c0 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java.off @@ -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 + */ +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"); + } +}