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");
+ }
+}