001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.markup.html.navigation.paging;
018
019import org.apache.wicket.Component;
020import org.apache.wicket.behavior.Behavior;
021import org.apache.wicket.markup.ComponentTag;
022import org.apache.wicket.markup.html.link.AbstractLink;
023import org.apache.wicket.markup.html.panel.Panel;
024
025/**
026 * A Wicket panel component to draw and maintain a complete page navigator, meant to be easily added
027 * to any PageableListView. A navigation which contains links to the first and last page, the
028 * current page +- some increment and which supports paged navigation bars (@see
029 * PageableListViewNavigationWithMargin).
030 * 
031 * @author Juergen Donnerstag
032 */
033public class PagingNavigator extends Panel
034{
035        private static final long serialVersionUID = 1L;
036
037        /** The navigation bar to be printed, e.g. 1 | 2 | 3 etc. */
038        private PagingNavigation pagingNavigation;
039        private final IPageable pageable;
040        private final IPagingLabelProvider labelProvider;
041
042        /**
043         * Constructor.
044         * 
045         * @param id
046         *            See Component
047         * @param pageable
048         *            The pageable component the page links are referring to.
049         */
050        public PagingNavigator(final String id, final IPageable pageable)
051        {
052                this(id, pageable, null);
053        }
054
055        /**
056         * Constructor.
057         * 
058         * @param id
059         *            See Component
060         * @param pageable
061         *            The pageable component the page links are referring to.
062         * @param labelProvider
063         *            The label provider for the link text.
064         */
065        public PagingNavigator(final String id, final IPageable pageable,
066                final IPagingLabelProvider labelProvider)
067        {
068                super(id);
069                this.pageable = pageable;
070                this.labelProvider = labelProvider;
071        }
072
073
074        /**
075         * {@link IPageable} this navigator is linked with
076         * 
077         * @return {@link IPageable} instance
078         */
079        public final IPageable getPageable()
080        {
081                return pageable;
082        }
083
084        @Override
085        protected void onInitialize()
086        {
087                super.onInitialize();
088
089                // Get the navigation bar and add it to the hierarchy
090                pagingNavigation = newNavigation("navigation", pageable, labelProvider);
091                add(pagingNavigation);
092
093                // Add additional page links
094                add(newPagingNavigationLink("first", pageable, 0).add(
095                        new TitleAppender("PagingNavigator.first")));
096                add(newPagingNavigationIncrementLink("prev", pageable, -1).add(
097                        new TitleAppender("PagingNavigator.previous")));
098                add(newPagingNavigationIncrementLink("next", pageable, 1).add(
099                        new TitleAppender("PagingNavigator.next")));
100                add(newPagingNavigationLink("last", pageable, -1).add(
101                        new TitleAppender("PagingNavigator.last")));
102        }
103
104        /**
105         * Create a new increment link. May be subclassed to make use of specialized links, e.g. Ajaxian
106         * links.
107         * 
108         * @param id
109         *            the link id
110         * @param pageable
111         *            the pageable to control
112         * @param increment
113         *            the increment
114         * @return the increment link
115         */
116        protected AbstractLink newPagingNavigationIncrementLink(String id, IPageable pageable,
117                int increment)
118        {
119                return new PagingNavigationIncrementLink<Void>(id, pageable, increment);
120        }
121
122        /**
123         * Create a new pagenumber link. May be subclassed to make use of specialized links, e.g.
124         * Ajaxian links.
125         * 
126         * @param id
127         *            the link id
128         * @param pageable
129         *            the pageable to control
130         * @param pageNumber
131         *            the page to jump to
132         * @return the pagenumber link
133         */
134        protected AbstractLink newPagingNavigationLink(String id, IPageable pageable, int pageNumber)
135        {
136                return new PagingNavigationLink<Void>(id, pageable, pageNumber);
137        }
138
139        /**
140         * Create a new PagingNavigation. May be subclassed to make us of specialized PagingNavigation.
141         * 
142         * @param id
143         *            The id of the navigation component
144         * @param pageable
145         *            the pageable component
146         * @param labelProvider
147         *            The label provider for the link text.
148         * @return the navigation object
149         */
150        protected PagingNavigation newNavigation(final String id, final IPageable pageable,
151                final IPagingLabelProvider labelProvider)
152        {
153                return new PagingNavigation(id, pageable, labelProvider);
154        }
155
156        /**
157         * Gets the pageable navigation component for configuration purposes.
158         * 
159         * @return the associated pageable navigation.
160         */
161        public final PagingNavigation getPagingNavigation()
162        {
163                return pagingNavigation;
164        }
165
166        /**
167         * Appends title attribute to navigation links
168         * 
169         * @author igor.vaynberg
170         */
171        private final class TitleAppender extends Behavior
172        {
173                private static final long serialVersionUID = 1L;
174
175                private final String resourceKey;
176
177                /**
178                 * Constructor
179                 * 
180                 * @param resourceKey
181                 *            resource key of the message
182                 */
183                public TitleAppender(String resourceKey)
184                {
185                        this.resourceKey = resourceKey;
186                }
187
188                /** {@inheritDoc} */
189                @Override
190                public void onComponentTag(Component component, ComponentTag tag)
191                {
192                        tag.put("title", PagingNavigator.this.getString(resourceKey));
193                }
194        }
195}