diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ContentCenterServlet.java b/ccm-cms/src/main/java/com/arsdigita/cms/ContentCenterServlet.java index 3b81d23c1..b5eecd808 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ContentCenterServlet.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ContentCenterServlet.java @@ -21,6 +21,7 @@ package com.arsdigita.cms; import com.arsdigita.bebop.Page; import com.arsdigita.cms.dispatcher.CMSPage; import com.arsdigita.cms.ui.CMSApplicationPage; +import com.arsdigita.cms.ui.contentcenter.MainPage; import com.arsdigita.dispatcher.DispatcherHelper; import com.arsdigita.dispatcher.RequestContext; @@ -99,10 +100,10 @@ public class ContentCenterServlet extends BaseApplicationServlet { // Addresses previously noted in WEB-INF/resources/content-center-map.xml // Obviously not required. -//ToDo -// addPage("/", new MainPage()); // index page at address ~/cc -// addPage("/index", new MainPage()); -//ToDo End + + addPage("/", new MainPage()); // index page at address ~/cc + addPage("/index", new MainPage()); + // addPage("/item-search", new CMSItemSearchPage()); // Old style diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSContainer.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSContainer.java new file mode 100755 index 000000000..e9b898b2a --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/CMSContainer.java @@ -0,0 +1,40 @@ +/* + * 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; + +import com.arsdigita.bebop.SimpleContainer; + + + +/** + * A simple container with XML wrapper tags. + * + * @author Michael Pih (pihman@arsdigita.com) + * @version $Id$ + */ +public class CMSContainer extends SimpleContainer { + + public final static String CMS_XML_NS = "http://www.arsdigita.com/cms/1.0"; + + + public CMSContainer() { + super("cms:container", CMS_XML_NS); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/GlobalNavigation.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/GlobalNavigation.java new file mode 100755 index 000000000..2da6aa9c1 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/GlobalNavigation.java @@ -0,0 +1,158 @@ +/* + * 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; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SimpleComponent; +import com.arsdigita.cms.CMS; +import com.arsdigita.cms.ContentCenter; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.ui.UI; +import com.arsdigita.ui.admin.AdminUiConstants; +import com.arsdigita.ui.login.LoginServlet; +import com.arsdigita.web.URL; +import com.arsdigita.xml.Element; + +import org.apache.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.core.CoreConstants; +import org.libreccm.security.PermissionChecker; +import org.libreccm.web.ApplicationCreator; +import org.libreccm.web.ApplicationManager; +import org.libreccm.web.ApplicationRepository; +import org.libreccm.web.ApplicationType; +import org.libreccm.web.CcmApplication; +import org.librecms.CmsConstants; + +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +/** + *
+ * Global navigation elements for the CMS admin UIs.
+ * + * @author Justin Ross <jross@redhat.com> + * @version $Id$ + */ +// Made public (instead of unspecified, resulting in protected) in 6.6.8 +public class GlobalNavigation extends SimpleComponent { + + private static final Logger s_log = Logger.getLogger(GlobalNavigation.class); + private final String m_adminPath; + private final String m_centerPath; + private final String m_changePasswordPath; + private final String m_helpPath; + private final String m_signOutPath; + private final String m_wspcPath; + + /** + * + */ + public GlobalNavigation() { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ApplicationManager appManager = cdiUtil.findBean( + ApplicationManager.class); + final ApplicationRepository appRepo = cdiUtil.findBean( + ApplicationRepository.class); + final MapThe context bar of the content center UI.
+ * + * @author Justin Ross <jross@redhat.com> + * @version $Id$ + */ +// Made public (instead of unspecified) in 6.6.8 +public class WorkspaceContextBar extends ContextBar { + + /** A logger instance, primarily to assist debugging . */ + private static final Logger s_log = Logger.getLogger + (WorkspaceContextBar.class); + + /** + * + * @param state + * @return + */ + @Override + protected List entries(final PageState state) { + + final List entries = super.entries(state); + + final String centerTitle = (String) new GlobalizedMessage("cms.ui.content_center", CmsConstants.CMS_BUNDLE).localize(); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ApplicationRepository appRepo = cdiUtil.findBean(ApplicationRepository.class); + final ListImage that uses the print listener
+ * to generate output.
+ *
+ * @param l the print listener used to produce output
+ */
+ public Image(PrintListener l) {
+ this("");
+ addPrintListener(l);
+ }
+
+ public void setImageURL(String imageURL) {
+ Assert.isUnlocked(this);
+ setAttribute(IMAGE_URL, imageURL);
+ }
+
+ public void setAlt(String alt) {
+ Assert.isUnlocked(this);
+ setAttribute(ALT, alt);
+ }
+ /**
+ *
+ *
+ * @param height
+ */
+ public void setHeight(String height) {
+ Assert.isUnlocked(this);
+ setAttribute(HEIGHT, height);
+ }
+
+ /**
+ *
+ *
+ * @param width
+ */
+ public void setWidth(String width) {
+ Assert.isUnlocked(this);
+ setAttribute(WIDTH, width);
+ }
+
+ /**
+ *
+ *
+ * @param border
+ */
+ public void setBorder(String border) {
+ Assert.isUnlocked(this);
+ setAttribute(BORDER, border);
+ }
+
+ /**
+ * Adds a print listener. Only one print listener can be set for an
+ * image, since the PrintListener is expected to modify the
+ * target of the PrintEvent.
+ * @param listener the print listener
+ * @throws IllegalArgumentException if listener is null.
+ * @throws IllegalStateException if a print listener has previously been
+ * added.
+ * @pre listener != null */
+ public void addPrintListener(PrintListener listener)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ if ( listener == null ) {
+ throw new IllegalArgumentException
+ ("Argument listener can not be null");
+ }
+ if ( m_printListener != null ) {
+ throw new IllegalStateException
+ ("Too many listeners. Can only have one");
+ }
+ m_printListener = listener;
+ }
+
+ /**
+ * Removes a previously added print listener. If listener is
+ * not the listener that was added with {@link #addPrintListener
+ * addPrintListener}, an IllegalArgumentException will be thrown.
+ * @param listener the listener that was previously added with
+ * addPrintListener
+ * @throws IllegalArgumentException if listener is not the
+ * currently registered print listener or is null.
+ * @pre listener != null
+ */
+ public void removePrintListener(PrintListener listener)
+ throws IllegalArgumentException
+ {
+ if ( listener == null ) {
+ throw new IllegalArgumentException("listener can not be null");
+ }
+ if ( listener != m_printListener ) {
+ throw new IllegalArgumentException
+ ("listener is not registered with this widget");
+ }
+ m_printListener = null;
+ }
+
+ /**
+ * Writes the output to a DOM to be used with the XSLT template
+ * to produce the appropriate output.
+ *
+ * Generates DOM fragment: + *
+ *
+ * @param parent the XML element to which the form adds its XML representation
+ * */
+ @Override
+ public void generateXML(PageState state, Element parent) {
+
+ if ( ! isVisible(state) ) {
+ return;
+ }
+
+ Image target = firePrintEvent(state);
+ Element image = parent.newChildElement ("bebop:image", BEBOP_XML_NS);
+ target.exportAttributes(image);
+ }
+
+ protected Image firePrintEvent(PageState state) {
+ Image i = this;
+ if ( m_printListener != null ) {
+ try {
+ i = (Image) this.clone();
+ m_printListener.prepare(new PrintEvent(this, state, i));
+ } catch ( CloneNotSupportedException e ) {
+ // FIXME: Failing silently here isn't so great
+ // It probably indicates a serious programming error
+ i = this;
+ }
+ }
+ return i;
+ }
+
+}
diff --git a/ccm-core/src/main/java/com/arsdigita/bebop/PaginationModelBuilder.java b/ccm-core/src/main/java/com/arsdigita/bebop/PaginationModelBuilder.java
new file mode 100755
index 000000000..892e971b3
--- /dev/null
+++ b/ccm-core/src/main/java/com/arsdigita/bebop/PaginationModelBuilder.java
@@ -0,0 +1,73 @@
+/*
+ * 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.bebop;
+
+/**
+ * A model builder for
+ * the {@link Paginator} component.
+ *
+ *
+ * <bebop:image [src=...] [alt=...] [height=...]
+ * [width=...] [border=...]/>
+ *
The {@link #getTotalSize(Paginator, PageState)} method of this
+ * class is called during the generation of page links for a
+ * Paginator component. When using a
+ * Paginator component with a {@link List} or a {@link
+ * Table}, you can achieve greater flexibility in terms of caching and
+ * performance by having the model builder implement this interface.
+ *
+ *
Unlike other model builder classes in Bebop, there is no
+ * PaginationModel class, as this would only be an int.
+ *
+ * @see Paginator
+ *
+ * @author Phong Nguyen
+ * @version $Id$
+ * @since 4.6.10
+ **/
+public interface PaginationModelBuilder {
+
+ // $Change: 44247 $
+ // $Revision$
+ // $DateTime: 2004/08/16 18:10:38 $
+ // $Author$
+
+ /**
+ * Returns the total number of results to paginate.
+ *
+ * @param paginator the Paginator instance that invoked this method
+ * @param state the current page state
+ * @return the total number of results to paginate.
+ **/
+ int getTotalSize(Paginator paginator, PageState state);
+
+ /**
+ * Determines whether the paginator should be visible in the request
+ * represented by state.
+ * This should normally delegate to the isVisible method of the
+ * associated displayed component.
+ *
+ * @return true if the paginator is visible in the request;
+ * false otherwise.
+ *
+ * @param state represents the current request
+ * @return true if the component is visible; false
+ * otherwise.
+ * @pre state != null
+ */
+ boolean isVisible(PageState state);
+
+}
diff --git a/ccm-core/src/main/java/com/arsdigita/bebop/Paginator.java b/ccm-core/src/main/java/com/arsdigita/bebop/Paginator.java
new file mode 100755
index 000000000..8bbac5f16
--- /dev/null
+++ b/ccm-core/src/main/java/com/arsdigita/bebop/Paginator.java
@@ -0,0 +1,518 @@
+/*
+ * 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.bebop;
+
+import com.arsdigita.bebop.list.ListModel;
+import com.arsdigita.bebop.list.ListModelBuilder;
+import com.arsdigita.bebop.parameters.IntegerParameter;
+import com.arsdigita.bebop.util.GlobalizationUtil;
+import com.arsdigita.util.LockableImpl;
+import com.arsdigita.xml.Element;
+
+/**
+ * A pagination component used to select different page views from a list of
+ * items.
+ *
+ *
In most cases, this component will be used with either a {@link + * List} or a {@link Table}. Here is an example on how to use this pagination + * component with a Table: + * + *
+ * + *+ * Table myTable = new Table(new myTableModelBuilder(), + * new DefaultTableColumnModel()); + * Paginator pgntr = new Paginator((PaginationModelBuilder) myTable.getModelBuilder(), 10); + * + * Page p = new Page(); + * p.add(pgntr); + * p.add(myTable); + *
The model builder that is used in
+ * myTable was designed to also implement the {@link PaginationModelBuilder}
+ * interface. With both interfaces being implemented by the same class, it is
+ * much easier to cache the results of operations performed on the {@link com.arsdigita.persistence.DataQuery}
+ * used to generate the results.
+ *
+ *
+ * + *+ * public class myTableModelBuilder extends LockableImpl + * implements TableModelBuilder, PaginatedModelBuilder { + * + * private RequestLocal m_query; + * + * public myTableModelBuilder() { + * super(); + * m_query = new RequestLocal(); + * } + * + * private getDataQuery(PageState state) { + * // returns the DataQuery used to generate rows for the table + * } + * + * public int getTotalSize(Paginator pgntr, PageState state) { + * DataQuery query = getDataQuery(state); + * query.setRange(new Integer(pgntr.getFirst(state)), + * new Integer(pgntr.getLast(state) + 1)); + * m_query.set(state, query); + * return (int) query.size(); + * } + * + * public TableModel makeModel(Table table, PageState state) { + * return new myTableModel(table, state, (DataQuery) m_query.get(state)); + * } + * } + *
Subclasses that wish to render the page links in a different format will
+ * override the {@link #buildPaginationDisplay()} method. The implementation of
+ * this method must set the selection model used to retrieve the page number by
+ * calling the {@link
+ * #setPageNumSelectionModel(SingleSelectionModel)} method. Aside from changing
+ * the display, this pagination component will hide itself if
+ * {@link PaginationModelBuilder#getTotalSize(Paginator, PageState)} is less
+ * than the page size (i.e., a single page can be used to display the entire
+ * results). This default behavior can be changed by calling {@link #setHiddenIfSinglePage(boolean)}
+ * with
+ * false.
+ *
+ * @see PaginationModelBuilder
+ *
+ * @author Phong Nguyen
+ * @version $Id$
+ * @since 4.6.10
+ *
+ */
+public class Paginator extends SimpleContainer implements Resettable {
+
+ // $Change: 44247 $
+ // $Revision$
+ // $DateTime: 2004/08/16 18:10:38 $
+ // $Author$
+ // The builder which returns the total number of items to
+ // paginate.
+ private PaginationModelBuilder m_builder;
+ // The selection model that returns the selected page number. The
+ // contained ParameterModel should be a StringParameter, since
+ // this is the default for List and Table.
+ private SingleSelectionModel m_pageNumModel;
+ // The selection model that returns the number of items to display
+ // for one page.
+ private SingleSelectionModel m_pageSizeModel;
+ // This is used to determine if this component should be hidden
+ // when there is only a single page to display. Defaults to true.
+ private boolean m_hiddenIfSinglePage;
+ // A label that contains a space, " ". This is used to insert
+ // spaces between the page links from within the list's
+ // generateXML() method.
+ private BoxPanel m_spacePanel;
+ private Label m_space;
+ // defined in List.java
+ private static final String _SELECT_EVENT = "s";
+
+ /**
+ * Constructor.
+ *
+ * @param builder The builder used to retrieve the total number of results
+ * to paginate.
+ * @param defaultPageSize The default number of results to display on each
+ * page.
+ *
+ */
+ public Paginator(PaginationModelBuilder builder, int defaultPageSize) {
+ super();
+
+ m_builder = builder;
+ m_hiddenIfSinglePage = true;
+
+ // Create the selection model which returns the size of one
+ // page and set its default value.
+ IntegerParameter sizeParam = new IntegerParameter("ps");
+ sizeParam.setDefaultValue(new Integer(defaultPageSize));
+ sizeParam.setDefaultOverridesNull(true);
+ m_pageSizeModel = new ParameterSingleSelectionModel(sizeParam);
+
+ // Builds the display for rendering page links, this also sets
+ // the page number selection model.
+ buildPaginationDisplay();
+ }
+
+ /**
+ * Builds the display for rendering the page links. Subclasses can override
+ * this method to provide a different rendering of the page links. If this
+ * is the case, make sure that the {@link
+ * #setPageNumSelectionModel(SingleSelectionModel)} method is called to set
+ * the selection model for retrieving the selected page number.
+ *
+ */
+ protected void buildPaginationDisplay() {
+ PaginatorList list = new PaginatorList(new PageListModelBuilder(this, getPaginationModelBuilder()));
+ setPageNumSelectionModel(list.getSelectionModel());
+
+ // This is used within the list's generateXML() method to
+ // insert spaces between the page links.
+ m_space = new Label(" ", false);
+ m_spacePanel = new BoxPanel(BoxPanel.HORIZONTAL);
+ m_spacePanel.add(m_space);
+
+ BoxPanel display = new BoxPanel(BoxPanel.HORIZONTAL);
+ display.add(new Label(GlobalizationUtil.globalize("bebop.page")));
+ display.add(list);
+ display.add(m_space);
+ add(display);
+ }
+
+ /**
+ * Sets the selection model that is used for returning the selected page
+ * number. Subclasses that override the {@link
+ * #buildPaginationDisplay()} method will need to call this method.
+ *
+ * @param pageNumModel The selection model used for returning the selected
+ * page number.
+ *
+ */
+ protected void setPageNumSelectionModel(SingleSelectionModel pageNumModel) {
+ m_pageNumModel = pageNumModel;
+ }
+
+ /**
+ * Returns the selected page number.
+ *
+ * @param state Represents the current state of the request.
+ * @return The selected page number.
+ *
+ */
+ public int getSelectedPageNum(PageState state) {
+ String pageNum = (String) m_pageNumModel.getSelectedKey(state);
+ if (pageNum == null) {
+ m_pageNumModel.setSelectedKey(state, "1");
+ return 1;
+ }
+ return Integer.parseInt(pageNum);
+ }
+
+ /**
+ * Sets the selected page number.
+ *
+ * @param state Represents the current state of the request.
+ * @param pageNum The number of the page to set as selected.
+ *
+ */
+ public void setSelectedPageNum(PageState state, int pageNum) {
+ m_pageNumModel.setSelectedKey(state, String.valueOf(pageNum));
+ }
+
+ /**
+ * Returns the number of items to display per page.
+ *
+ * @param state Represents the current state of the request.
+ * @return The number of items to display per page.
+ *
+ */
+ public int getPageSize(PageState state) {
+ return ((Integer) m_pageSizeModel.getSelectedKey(state)).intValue();
+ }
+
+ /**
+ * Sets the number of items to display per page.
+ *
+ * @param state Represents the current state of the request.
+ * @param pageSize The number of items to display per page.
+ *
+ */
+ public void setPageSize(PageState state, int pageSize) {
+ m_pageSizeModel.setSelectedKey(state, new Integer(pageSize));
+ }
+
+ /**
+ * This returns the total number of pages that will be displayed by this
+ * paginator.
+ *
+ * @param state The page state
+ */
+ public int getTotalPages(PageState state) {
+ int totalSize = m_builder.getTotalSize(this, state);
+ int pageSize = getPageSize(state);
+ int minSize = totalSize / pageSize;
+ if (minSize * pageSize == totalSize) {
+ return minSize;
+ } else {
+ return minSize + 1;
+ }
+ }
+
+ /**
+ * Returns the number of the first item to display.
+ *
+ * @param state Represents the current state of the request.
+ * @return The number of the first item to display.
+ *
+ */
+ public int getFirst(PageState state) {
+ return ((getSelectedPageNum(state) - 1) * getPageSize(state)) + 1;
+ }
+
+ /**
+ * Returns the number of the last item to display.
+ *
+ * @param state Represents the current state of the request.
+ * @return The number of teh last item to display.
+ *
+ */
+ public int getLast(PageState state) {
+ // NOTE: If the returned integer is used for
+ // DataQuery.setRange(int, int), then it needs to be
+ // incremented by 1.
+ return (getSelectedPageNum(state) * getPageSize(state));
+ }
+
+ /**
+ * Returns the builder that is used to retrieve the total number of items to
+ * paginate.
+ *
+ * @return The builder used to compute the total number of items to
+ * paginate.
+ *
+ */
+ public PaginationModelBuilder getPaginationModelBuilder() {
+ return m_builder;
+ }
+
+ /**
+ * Specifies whether this component is hidden if there is only a single page
+ * of items to display.
+ *
+ * @return Returns
+ * true if this component is hidden when there is only a single
+ * page to view.
+ *
+ */
+ public boolean isHiddenIfSinglePage() {
+ return m_hiddenIfSinglePage;
+ }
+
+ /**
+ * Sets whether or not this component should be hidden if there is only a
+ * single page of items to display.
+ *
+ * @param isHidden By default, this component will be hidden when there is
+ * only a single page to display. Set this to
+ * false if this is not the desired effect.
+ *
+ */
+ public void setHiddenIfSinglePage(boolean isHidden) {
+ m_hiddenIfSinglePage = isHidden;
+ }
+
+ /**
+ * Returns
+ * true if this component is visible. This component will not
+ * be visible if the paginator model builder's isVisible method reports
+ * false. If this component is set to be hidden when there is only a single
+ * page to display, then the total page size returned from the {@link PaginationModelBuilder}
+ * object must be greater than the number of items per page.
+ *
+ * @param state Represents the current state of the request.
+ * @return Returns
+ * true if this component is visible.
+ *
+ * @see #getPageSize(PageState)
+ * @see PaginationModelBuilder#getTotalSize(Paginator, PageState)
+ *
+ */
+ @Override
+ public boolean isVisible(PageState state) {
+ return (super.isVisible(state)
+ && m_builder.isVisible(state)
+ && ((!m_hiddenIfSinglePage)
+ || m_builder.getTotalSize(this, state) > getPageSize(state)));
+ }
+
+ /**
+ * Register the page size selection model.
+ *
+ * @param p The page to register with.
+ *
+ */
+ @Override
+ public void register(Page p) {
+ super.register(p);
+ p.setVisibleDefault(m_spacePanel, false);
+ p.addComponentStateParam(this, m_pageSizeModel.getStateParameter());
+ }
+
+ /**
+ * Resets this component by clearing the selected page.
+ *
+ * @param state Represents the current state of the request.
+ *
+ */
+ public void reset(PageState state) {
+ m_pageNumModel.clearSelection(state);
+ }
+
+ /**
+ * This class was added to provide greater flexibility in displaying the
+ * page links. Links can be displayed in a space separated list to support
+ * wrapping or in a table with a fixed number of page links per row. By
+ * default the page links will be rendered inside a one-cell table. If the
+ * number of page links to display per line is specified, then each page
+ * link will be rendered in it's own cell.
+ *
+ */
+ private class PaginatorList extends List {
+
+ public PaginatorList(ListModelBuilder builder) {
+ super(builder);
+ }
+
+ /**
+ * If the number of page links to display per line is specified then the
+ * generated xml will be similar to that of a Table. Else, it will be
+ * similar to a simple container.
+ *
+ * @param state Represents the current state of the request.
+ * @param parent The element to which to attach the XML.
+ *
+ */
+ @Override
+ public void generateXML(PageState state, Element parent) {
+ if (!this.isVisible(state)) {
+ return;
+ }
+
+ // maybe display the Previous arrow
+ if (getSelectedPageNum(state) > 1) {
+ state.setControlEvent(this, _SELECT_EVENT,
+ Integer.toString(getSelectedPageNum(state) - 1));
+ (new ControlLink(new Label("<"))).generateXML(state, parent);
+ (new Label(" ")).generateXML(state, parent);
+ state.setControlEvent(this, _SELECT_EVENT,
+ Integer.toString(getSelectedPageNum(state) - 1));
+ (new ControlLink(new Label(GlobalizationUtil.globalize("bebop.previous")))).generateXML(state, parent);
+ (new Label(" ")).generateXML(state, parent);
+ }
+
+ ListModel m = getModel(state);
+ Object selKey = getSelectedKey(state);
+ Component c;
+ int i = 0;
+ while (m.next()) {
+ String key = m.getKey();
+ // Converting both keys to String for comparison
+ // since ListModel.getKey returns a String
+ boolean selected = (selKey != null) && (key != null)
+ && selKey.toString().equals(key.toString());
+
+ state.setControlEvent(this, _SELECT_EVENT, m.getKey());
+ c = getCellRenderer().getComponent(this, state, m.getElement(),
+ m.getKey(), i, selected);
+ c.generateXML(state, parent);
+ m_space.generateXML(state, parent);
+ i += 1;
+ }
+
+ // maybe display the next arrow
+ if (getSelectedPageNum(state) < getTotalPages(state)) {
+ state.setControlEvent(this, _SELECT_EVENT,
+ Integer.toString(getSelectedPageNum(state) + 1));
+ (new Label(" ")).generateXML(state, parent);
+ (new ControlLink(new Label(GlobalizationUtil.globalize("bebop.next")))).generateXML(state, parent);
+ (new Label(" ")).generateXML(state, parent);
+ state.setControlEvent(this, _SELECT_EVENT,
+ Integer.toString(getSelectedPageNum(state) + 1));
+ (new ControlLink(new Label(">"))).generateXML(state, parent);
+ }
+
+ state.clearControlEvent();
+ }
+ }
+
+ /**
+ * A list model builder for the pagination list.
+ *
+ */
+ private class PageListModelBuilder extends LockableImpl
+ implements ListModelBuilder {
+
+ Paginator m_paginator;
+ PaginationModelBuilder m_builder;
+
+ public PageListModelBuilder(Paginator paginator,
+ PaginationModelBuilder builder) {
+ super();
+ m_paginator = paginator;
+ m_builder = builder;
+ }
+
+ public ListModel makeModel(List list, PageState state) {
+ return new PageListModel(m_builder.getTotalSize(m_paginator, state),
+ getPageSize(state),
+ getSelectedPageNum(state));
+ }
+ }
+
+ /**
+ * A list model for the pagination list which is used to generate the text
+ * for the page links.
+ *
+ */
+ private class PageListModel extends LockableImpl
+ implements ListModel {
+
+ int m_totalSize;
+ int m_pageSize;
+ int m_pageCount;
+ int m_current;
+
+ public PageListModel(int totalSize, int pageSize, int current) {
+ super();
+ m_totalSize = totalSize;
+ m_pageSize = pageSize;
+ m_pageCount = 0;
+ m_current = current;
+ }
+
+ public boolean next() {
+ if (m_pageCount * m_pageSize < m_totalSize) {
+ m_pageCount += 1;
+ return true;
+ }
+ return false;
+ }
+
+ public Object getElement() {
+ /*
+ * TODO: Remove or relocate this int begin = ((m_pageCount-1) *
+ * m_pageSize) + 1; int end = (m_pageCount) * m_pageSize; if (end >
+ * m_totalSize) { end = m_totalSize; } return "" + begin + "-" +
+ * end;
+ */
+ if (Math.abs(m_current - m_pageCount) <= 5
+ || m_pageCount == 1
+ || m_pageCount * m_pageSize >= m_totalSize) {
+ return Integer.toString(m_pageCount);
+ } else {
+ return ".";
+ }
+ }
+
+ public String getKey() {
+ return Integer.toString(m_pageCount);
+ }
+ }
+}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ContextBar.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ContextBar.java
new file mode 100755
index 000000000..422cd5f04
--- /dev/null
+++ b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ContextBar.java
@@ -0,0 +1,93 @@
+/*
+ * 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.toolbox.ui;
+
+import com.arsdigita.bebop.SimpleComponent;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.RequestLocal;
+import com.arsdigita.web.URL;
+import com.arsdigita.util.Assert;
+import com.arsdigita.xml.Element;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.log4j.Logger;
+
+/**
+ *
A context bar.
+ * + * @author Justin Ross <jross@redhat.com> + * @version $Id$ + */ +public abstract class ContextBar extends SimpleComponent { + + private static final Logger s_log = Logger.getLogger(ContextBar.class); + + private static final RequestLocal s_entries = new RequestLocal() { + protected final Object initialValue(final PageState state) { + return new ArrayList(); + } + }; + + public ContextBar() { + super(); + } + + protected List entries(final PageState state) { + return (List) s_entries.get(state); + } + + public final void generateXML(final PageState state, final Element parent) { + if (isVisible(state)) { + final Element nav = parent.newChildElement + ("bebop:contextBar", BEBOP_XML_NS); + + for (Iterator iter = entries(state).iterator(); iter.hasNext(); ) { + ((Entry) iter.next()).generateXML(state, nav); + } + } + } + + public static final class Entry { + private final String m_title; + private final String m_href; + + public Entry(final String title, final String href) { + super(); + + Assert.exists(title, "String title"); + + m_title = title; + m_href = href; + } + + public Entry(final String title, final URL url) { + this(title, url.toString()); + } + + public void generateXML(final PageState state, + final Element parent) { + final Element elem = parent.newChildElement + ("bebop:entry", BEBOP_XML_NS); + + elem.addAttribute("title", m_title); + elem.addAttribute("href", m_href); + } + } +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/CcmObjectSelectionModel.java b/ccm-core/src/main/java/com/arsdigita/ui/CcmObjectSelectionModel.java index d6867494c..1c5bdd2c7 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/CcmObjectSelectionModel.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/CcmObjectSelectionModel.java @@ -31,47 +31,47 @@ import org.libreccm.core.CcmObjectRepository; /** * @param