diff options
Diffstat (limited to 'src/main/java/com/gitblit')
19 files changed, 725 insertions, 226 deletions
diff --git a/src/main/java/com/gitblit/extensions/GitblitWicketPlugin.java b/src/main/java/com/gitblit/extensions/GitblitWicketPlugin.java new file mode 100644 index 00000000..130f4993 --- /dev/null +++ b/src/main/java/com/gitblit/extensions/GitblitWicketPlugin.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.extensions; + +import org.apache.wicket.Application; +import org.apache.wicket.IInitializer; + +import ro.fortsoft.pf4j.PluginWrapper; + +import com.gitblit.wicket.GitblitWicketApp; + +/** + * A Gitblit plugin that is allowed to extend the Wicket webapp. + * + * @author James Moger + * @since 1.6.0 + */ +public abstract class GitblitWicketPlugin extends GitblitPlugin implements IInitializer { + + public GitblitWicketPlugin(PluginWrapper wrapper) { + super(wrapper); + } + + @Override + public final void init(Application application) { + init((GitblitWicketApp) application); + } + + /** + * Allows plugins to extend the web application. + * + * @param app + * @since 1.6.0 + */ + protected abstract void init(GitblitWicketApp app); +}
\ No newline at end of file diff --git a/src/main/java/com/gitblit/extensions/AdminMenuExtension.java b/src/main/java/com/gitblit/extensions/NavLinkExtension.java index 8fe4288f..c8958603 100644 --- a/src/main/java/com/gitblit/extensions/AdminMenuExtension.java +++ b/src/main/java/com/gitblit/extensions/NavLinkExtension.java @@ -19,22 +19,22 @@ import java.util.List; import ro.fortsoft.pf4j.ExtensionPoint; -import com.gitblit.models.Menu.MenuItem; +import com.gitblit.models.NavLink; import com.gitblit.models.UserModel; /** - * Extension point to contribute administration menu items. + * Extension point to contribute top-level navigation links. * * @author James Moger * @since 1.6.0 * */ -public abstract class AdminMenuExtension implements ExtensionPoint { +public abstract class NavLinkExtension implements ExtensionPoint { /** * @param user * @since 1.6.0 - * @return a list of menu items + * @return a list of nav links */ - public abstract List<MenuItem> getMenuItems(UserModel user); + public abstract List<NavLink> getNavLinks(UserModel user); } diff --git a/src/main/java/com/gitblit/extensions/RepositoryNavLinkExtension.java b/src/main/java/com/gitblit/extensions/RepositoryNavLinkExtension.java new file mode 100644 index 00000000..2b05c5a0 --- /dev/null +++ b/src/main/java/com/gitblit/extensions/RepositoryNavLinkExtension.java @@ -0,0 +1,42 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.extensions; + +import java.util.List; + +import ro.fortsoft.pf4j.ExtensionPoint; + +import com.gitblit.models.NavLink; +import com.gitblit.models.RepositoryModel; +import com.gitblit.models.UserModel; + +/** + * Extension point to contribute repository page navigation links. + * + * @author James Moger + * @since 1.6.0 + * + */ +public abstract class RepositoryNavLinkExtension implements ExtensionPoint { + + /** + * @param user + * @param repository + * @since 1.6.0 + * @return a list of nav links + */ + public abstract List<NavLink> getNavLinks(UserModel user, RepositoryModel repository); +} diff --git a/src/main/java/com/gitblit/models/NavLink.java b/src/main/java/com/gitblit/models/NavLink.java new file mode 100644 index 00000000..993d6954 --- /dev/null +++ b/src/main/java/com/gitblit/models/NavLink.java @@ -0,0 +1,140 @@ +/*
+ * Copyright 2011 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.models;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.markup.html.WebPage;
+
+import com.gitblit.models.Menu.MenuItem;
+
+/**
+ * Represents a navigation link for the navigation panel.
+ *
+ * @author James Moger
+ *
+ */
+public abstract class NavLink implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public final String translationKey;
+ public final boolean hiddenPhone;
+
+ public NavLink(String translationKey, boolean hiddenPhone) {
+ this.translationKey = translationKey;
+ this.hiddenPhone = hiddenPhone;
+ }
+
+
+ /**
+ * Represents a Wicket page link.
+ *
+ * @author James Moger
+ *
+ */
+ public static class PageNavLink extends NavLink implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public final Class<? extends WebPage> pageClass;
+ public final PageParameters params;
+
+ public PageNavLink(String translationKey, Class<? extends WebPage> pageClass) {
+ this(translationKey, pageClass, null);
+ }
+
+ public PageNavLink(String translationKey, Class<? extends WebPage> pageClass,
+ PageParameters params) {
+ this(translationKey, pageClass, params, false);
+ }
+
+ public PageNavLink(String translationKey, Class<? extends WebPage> pageClass,
+ PageParameters params, boolean hiddenPhone) {
+ super(translationKey, hiddenPhone);
+ this.pageClass = pageClass;
+ this.params = params;
+ }
+ }
+
+ /**
+ * Represents an explicitly href link.
+ *
+ * @author James Moger
+ *
+ */
+ public static class ExternalNavLink extends NavLink implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public final String url;
+
+ public ExternalNavLink(String keyOrText, String url) {
+ super(keyOrText, false);
+ this.url = url;
+ }
+
+ public ExternalNavLink(String keyOrText, String url, boolean hiddenPhone) {
+ super(keyOrText, hiddenPhone);
+ this.url = url;
+ }
+ }
+
+ /**
+ * Represents a DropDownMenu for the current page.
+ *
+ * @author James Moger
+ *
+ */
+ public static class DropDownPageMenuNavLink extends PageNavLink implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public final List<MenuItem> menuItems;
+
+ public DropDownPageMenuNavLink(String keyOrText, Class<? extends WebPage> pageClass) {
+ this(keyOrText, pageClass, false);
+ }
+
+ public DropDownPageMenuNavLink(String keyOrText, Class<? extends WebPage> pageClass, boolean hiddenPhone) {
+ super(keyOrText, pageClass, null, hiddenPhone);
+ menuItems = new ArrayList<MenuItem>();
+ }
+ }
+
+ /**
+ * Represents a DropDownMenu.
+ *
+ * @author James Moger
+ *
+ */
+ public static class DropDownMenuNavLink extends NavLink implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public final List<MenuItem> menuItems;
+
+ public DropDownMenuNavLink(String keyOrText) {
+ this(keyOrText, false);
+ }
+
+ public DropDownMenuNavLink(String keyOrText, boolean hiddenPhone) {
+ super(keyOrText, hiddenPhone);
+ menuItems = new ArrayList<MenuItem>();
+ }
+ }
+}
\ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java index 3ca7d48f..d3aa62fd 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java @@ -28,8 +28,12 @@ import org.apache.wicket.Session; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.protocol.http.WebApplication; +import ro.fortsoft.pf4j.PluginState; +import ro.fortsoft.pf4j.PluginWrapper; + import com.gitblit.IStoredSettings; import com.gitblit.Keys; +import com.gitblit.extensions.GitblitWicketPlugin; import com.gitblit.manager.IAuthenticationManager; import com.gitblit.manager.IFederationManager; import com.gitblit.manager.IGitblit; @@ -83,7 +87,7 @@ import com.gitblit.wicket.pages.TreePage; import com.gitblit.wicket.pages.UserPage; import com.gitblit.wicket.pages.UsersPage; -public class GitBlitWebApp extends WebApplication { +public class GitBlitWebApp extends WebApplication implements GitblitWicketApp { private final Class<? extends WebPage> homePageClass = MyDashboardPage.class; @@ -210,11 +214,29 @@ public class GitBlitWebApp extends WebApplication { mount("/forks", ForksPage.class, "r"); mount("/fork", ForkPage.class, "r"); + // allow started Wicket plugins to initialize + for (PluginWrapper pluginWrapper : pluginManager.getPlugins()) { + if (PluginState.STARTED != pluginWrapper.getPluginState()) { + continue; + } + if (pluginWrapper.getPlugin() instanceof GitblitWicketPlugin) { + GitblitWicketPlugin wicketPlugin = (GitblitWicketPlugin) pluginWrapper.getPlugin(); + wicketPlugin.init(this); + } + } + + // customize the Wicket class resolver to load from plugins + PluginClassResolver classResolver = new PluginClassResolver(pluginManager); + getApplicationSettings().setClassResolver(classResolver); + getMarkupSettings().setDefaultMarkupEncoding("UTF-8"); - super.init(); } - private void mount(String location, Class<? extends WebPage> clazz, String... parameters) { + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#mount(java.lang.String, java.lang.Class, java.lang.String) + */ + @Override + public void mount(String location, Class<? extends WebPage> clazz, String... parameters) { if (parameters == null) { parameters = new String[] {}; } @@ -230,15 +252,26 @@ public class GitBlitWebApp extends WebApplication { } } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#getHomePage() + */ @Override public Class<? extends WebPage> getHomePage() { return homePageClass; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#isCacheablePage(java.lang.String) + */ + @Override public boolean isCacheablePage(String mountPoint) { return cacheablePages.containsKey(mountPoint); } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#getCacheControl(java.lang.String) + */ + @Override public CacheControl getCacheControl(String mountPoint) { return cacheablePages.get(mountPoint); } @@ -254,15 +287,18 @@ public class GitBlitWebApp extends WebApplication { return gitBlitWebSession; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#settings() + */ + @Override public IStoredSettings settings() { return settings; } - /** - * Is Gitblit running in debug mode? - * - * @return true if Gitblit is running in debug mode + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#isDebugMode() */ + @Override public boolean isDebugMode() { return runtimeManager.isDebugMode(); } @@ -271,58 +307,114 @@ public class GitBlitWebApp extends WebApplication { * These methods look strange... and they are... but they are the first * step towards modularization across multiple commits. */ + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#getBootDate() + */ + @Override public Date getBootDate() { return runtimeManager.getBootDate(); } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#getLastActivityDate() + */ + @Override public Date getLastActivityDate() { return repositoryManager.getLastActivityDate(); } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#runtime() + */ + @Override public IRuntimeManager runtime() { return runtimeManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#plugins() + */ + @Override public IPluginManager plugins() { return pluginManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#notifier() + */ + @Override public INotificationManager notifier() { return notificationManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#users() + */ + @Override public IUserManager users() { return userManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#authentication() + */ + @Override public IAuthenticationManager authentication() { return authenticationManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#keys() + */ + @Override public IPublicKeyManager keys() { return publicKeyManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#repositories() + */ + @Override public IRepositoryManager repositories() { return repositoryManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#projects() + */ + @Override public IProjectManager projects() { return projectManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#federation() + */ + @Override public IFederationManager federation() { return federationManager; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#gitblit() + */ + @Override public IGitblit gitblit() { return gitblit; } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#tickets() + */ + @Override public ITicketService tickets() { return gitblit.getTicketService(); } + /* (non-Javadoc) + * @see com.gitblit.wicket.Webapp#getTimezone() + */ + @Override public TimeZone getTimezone() { return runtimeManager.getTimezone(); } diff --git a/src/main/java/com/gitblit/wicket/GitblitWicketApp.java b/src/main/java/com/gitblit/wicket/GitblitWicketApp.java new file mode 100644 index 00000000..a56e6996 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/GitblitWicketApp.java @@ -0,0 +1,72 @@ +package com.gitblit.wicket; + +import java.util.Date; +import java.util.TimeZone; + +import org.apache.wicket.markup.html.WebPage; + +import com.gitblit.IStoredSettings; +import com.gitblit.manager.IAuthenticationManager; +import com.gitblit.manager.IFederationManager; +import com.gitblit.manager.IGitblit; +import com.gitblit.manager.INotificationManager; +import com.gitblit.manager.IPluginManager; +import com.gitblit.manager.IProjectManager; +import com.gitblit.manager.IRepositoryManager; +import com.gitblit.manager.IRuntimeManager; +import com.gitblit.manager.IUserManager; +import com.gitblit.tickets.ITicketService; +import com.gitblit.transport.ssh.IPublicKeyManager; + +public interface GitblitWicketApp { + + public abstract void mount(String location, Class<? extends WebPage> clazz, String... parameters); + + public abstract Class<? extends WebPage> getHomePage(); + + public abstract boolean isCacheablePage(String mountPoint); + + public abstract CacheControl getCacheControl(String mountPoint); + + public abstract IStoredSettings settings(); + + /** + * Is Gitblit running in debug mode? + * + * @return true if Gitblit is running in debug mode + */ + public abstract boolean isDebugMode(); + + /* + * These methods look strange... and they are... but they are the first + * step towards modularization across multiple commits. + */ + public abstract Date getBootDate(); + + public abstract Date getLastActivityDate(); + + public abstract IRuntimeManager runtime(); + + public abstract IPluginManager plugins(); + + public abstract INotificationManager notifier(); + + public abstract IUserManager users(); + + public abstract IAuthenticationManager authentication(); + + public abstract IPublicKeyManager keys(); + + public abstract IRepositoryManager repositories(); + + public abstract IProjectManager projects(); + + public abstract IFederationManager federation(); + + public abstract IGitblit gitblit(); + + public abstract ITicketService tickets(); + + public abstract TimeZone getTimezone(); + +}
\ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/PageRegistration.java b/src/main/java/com/gitblit/wicket/PageRegistration.java deleted file mode 100644 index 9fd8f870..00000000 --- a/src/main/java/com/gitblit/wicket/PageRegistration.java +++ /dev/null @@ -1,99 +0,0 @@ -/*
- * Copyright 2011 gitblit.com.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gitblit.wicket;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.wicket.PageParameters;
-import org.apache.wicket.markup.html.WebPage;
-
-import com.gitblit.models.Menu.MenuItem;
-
-/**
- * Represents a page link registration for the topbar.
- *
- * @author James Moger
- *
- */
-public class PageRegistration implements Serializable {
- private static final long serialVersionUID = 1L;
-
- public final String translationKey;
- public final Class<? extends WebPage> pageClass;
- public final PageParameters params;
- public final boolean hiddenPhone;
-
- public PageRegistration(String translationKey, Class<? extends WebPage> pageClass) {
- this(translationKey, pageClass, null);
- }
-
- public PageRegistration(String translationKey, Class<? extends WebPage> pageClass,
- PageParameters params) {
- this(translationKey, pageClass, params, false);
- }
-
- public PageRegistration(String translationKey, Class<? extends WebPage> pageClass,
- PageParameters params, boolean hiddenPhone) {
- this.translationKey = translationKey;
- this.pageClass = pageClass;
- this.params = params;
- this.hiddenPhone = hiddenPhone;
- }
-
- /**
- * Represents a page link to a non-Wicket page. Might be external.
- *
- * @author James Moger
- *
- */
- public static class OtherPageLink extends PageRegistration {
-
- private static final long serialVersionUID = 1L;
-
- public final String url;
-
- public OtherPageLink(String keyOrText, String url) {
- super(keyOrText, null);
- this.url = url;
- }
-
- public OtherPageLink(String keyOrText, String url, boolean hiddenPhone) {
- super(keyOrText, null, null, hiddenPhone);
- this.url = url;
- }
- }
-
- /**
- * Represents a DropDownMenu for the topbar
- *
- * @author James Moger
- *
- */
- public static class DropDownMenuRegistration extends PageRegistration {
-
- private static final long serialVersionUID = 1L;
-
- public final List<MenuItem> menuItems;
-
- public DropDownMenuRegistration(String keyOrText, Class<? extends WebPage> pageClass) {
- super(keyOrText, pageClass);
- menuItems = new ArrayList<MenuItem>();
- }
- }
-
-}
\ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/PluginClassResolver.java b/src/main/java/com/gitblit/wicket/PluginClassResolver.java new file mode 100644 index 00000000..ba53b04b --- /dev/null +++ b/src/main/java/com/gitblit/wicket/PluginClassResolver.java @@ -0,0 +1,122 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.wicket; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.wicket.Application; +import org.apache.wicket.WicketRuntimeException; +import org.apache.wicket.application.IClassResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ro.fortsoft.pf4j.PluginState; +import ro.fortsoft.pf4j.PluginWrapper; + +import com.gitblit.manager.IPluginManager; + +/** + * Resolves plugin classes and resources. + */ +public class PluginClassResolver implements IClassResolver { + private static final Logger logger = LoggerFactory.getLogger(PluginClassResolver.class); + + private final IPluginManager pluginManager; + + public PluginClassResolver(IPluginManager pluginManager) { + this.pluginManager = pluginManager; + } + + @Override + public Class<?> resolveClass(final String className) throws ClassNotFoundException { + boolean debugEnabled = logger.isDebugEnabled(); + + for (PluginWrapper plugin : pluginManager.getPlugins()) { + if (PluginState.STARTED != plugin.getPluginState()) { + // ignore this plugin + continue; + } + + try { + return plugin.getPluginClassLoader().loadClass(className); + } catch (ClassNotFoundException cnfx) { + if (debugEnabled) { + logger.debug("ClassResolver '{}' cannot find class: '{}'", plugin.getPluginId(), className); + } + } + } + + throw new ClassNotFoundException(className); + } + + @Override + public Iterator<URL> getResources(final String name) { + Set<URL> urls = new TreeSet<URL>(new UrlExternalFormComparator()); + + for (PluginWrapper plugin : pluginManager.getPlugins()) { + if (PluginState.STARTED != plugin.getPluginState()) { + // ignore this plugin + continue; + } + + Iterator<URL> it = getResources(name, plugin); + while (it.hasNext()) { + URL url = it.next(); + urls.add(url); + } + } + + return urls.iterator(); + } + + protected Iterator<URL> getResources(String name, PluginWrapper plugin) { + HashSet<URL> loadedFiles = new HashSet<URL>(); + try { + // Try the classloader for the wicket jar/bundle + Enumeration<URL> resources = plugin.getPluginClassLoader().getResources(name); + loadResources(resources, loadedFiles); + + // Try the classloader for the user's application jar/bundle + resources = Application.get().getClass().getClassLoader().getResources(name); + loadResources(resources, loadedFiles); + + // Try the context class loader + resources = Thread.currentThread().getContextClassLoader().getResources(name); + loadResources(resources, loadedFiles); + } catch (IOException e) { + throw new WicketRuntimeException(e); + } + + return loadedFiles.iterator(); + } + + private void loadResources(Enumeration<URL> resources, Set<URL> loadedFiles) { + if (resources != null) { + while (resources.hasMoreElements()) { + final URL url = resources.nextElement(); + if (!loadedFiles.contains(url)) { + loadedFiles.add(url); + } + } + } + } +}
\ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/UrlExternalFormComparator.java b/src/main/java/com/gitblit/wicket/UrlExternalFormComparator.java new file mode 100644 index 00000000..90f4b320 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/UrlExternalFormComparator.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.wicket; + +import java.net.URL; +import java.util.Comparator; + +/** + * A comparator of URL instances. + * + * Comparing URLs with their implementation of #equals() is + * bad because it may cause problems like DNS resolving, or other + * slow checks. This comparator uses the external form of an URL + * to make a simple comparison of two Strings. + * + * @since 1.5.6 + */ +public class UrlExternalFormComparator implements Comparator<URL> +{ + @Override + public int compare(URL url1, URL url2) + { + return url1.toExternalForm().compareTo(url2.toExternalForm()); + } +}
\ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/pages/ActivityPage.java b/src/main/java/com/gitblit/wicket/pages/ActivityPage.java index 0870ff96..c505a666 100644 --- a/src/main/java/com/gitblit/wicket/pages/ActivityPage.java +++ b/src/main/java/com/gitblit/wicket/pages/ActivityPage.java @@ -32,14 +32,14 @@ import org.apache.wicket.markup.html.panel.Fragment; import com.gitblit.Keys;
import com.gitblit.models.Activity;
import com.gitblit.models.Menu.ParameterMenuItem;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
import com.gitblit.models.Metric;
+import com.gitblit.models.NavLink;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.ActivityUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.charting.Chart;
import com.gitblit.wicket.charting.Charts;
@@ -135,8 +135,8 @@ public class ActivityPage extends RootPage { }
@Override
- protected void addDropDownMenus(List<PageRegistration> pages) {
- DropDownMenuRegistration filters = new DropDownMenuRegistration("gb.filters",
+ protected void addDropDownMenus(List<NavLink> navLinks) {
+ DropDownPageMenuNavLink filters = new DropDownPageMenuNavLink("gb.filters",
ActivityPage.class);
PageParameters currentParameters = getPageParameters();
@@ -155,7 +155,7 @@ public class ActivityPage extends RootPage { // Reset Filter
filters.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
}
- pages.add(filters);
+ navLinks.add(filters);
}
/**
diff --git a/src/main/java/com/gitblit/wicket/pages/DashboardPage.java b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java index 16b0b734..9c10e01b 100644 --- a/src/main/java/com/gitblit/wicket/pages/DashboardPage.java +++ b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java @@ -37,7 +37,9 @@ import org.eclipse.jgit.lib.Repository; import com.gitblit.Keys;
import com.gitblit.models.DailyLogEntry;
import com.gitblit.models.Menu.ParameterMenuItem;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
import com.gitblit.models.Metric;
+import com.gitblit.models.NavLink;
import com.gitblit.models.RefLogEntry;
import com.gitblit.models.RepositoryCommit;
import com.gitblit.models.RepositoryModel;
@@ -46,8 +48,6 @@ import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.RefLogUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebApp;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.charting.Chart;
import com.gitblit.wicket.charting.Charts;
import com.gitblit.wicket.charting.Flotr2Charts;
@@ -141,10 +141,10 @@ public abstract class DashboardPage extends RootPage { }
@Override
- protected void addDropDownMenus(List<PageRegistration> pages) {
+ protected void addDropDownMenus(List<NavLink> navLinks) {
PageParameters params = getPageParameters();
- DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
+ DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
GitBlitWebApp.get().getHomePage());
// preserve repository filter option on time choices
@@ -155,7 +155,7 @@ public abstract class DashboardPage extends RootPage { menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
}
- pages.add(menu);
+ navLinks.add(menu);
}
diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectPage.java b/src/main/java/com/gitblit/wicket/pages/ProjectPage.java index 6c8aa4f4..d358b775 100644 --- a/src/main/java/com/gitblit/wicket/pages/ProjectPage.java +++ b/src/main/java/com/gitblit/wicket/pages/ProjectPage.java @@ -29,6 +29,8 @@ import com.gitblit.Keys; import com.gitblit.models.Menu.MenuDivider;
import com.gitblit.models.Menu.MenuItem;
import com.gitblit.models.Menu.ParameterMenuItem;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
+import com.gitblit.models.NavLink;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
@@ -40,8 +42,6 @@ import com.gitblit.wicket.CacheControl.LastModified; import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.FilterableRepositoryList;
@@ -161,10 +161,10 @@ public class ProjectPage extends DashboardPage { }
@Override
- protected void addDropDownMenus(List<PageRegistration> pages) {
+ protected void addDropDownMenus(List<NavLink> navLinks) {
PageParameters params = getPageParameters();
- DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
+ DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
ProjectPage.class);
// preserve time filter option on repository choices
menu.menuItems.addAll(getRepositoryFilterItems(params));
@@ -177,12 +177,12 @@ public class ProjectPage extends DashboardPage { menu.menuItems.add(new ParameterMenuItem(getString("gb.reset"), "p", WicketUtils.getProjectName(params)));
}
- pages.add(menu);
+ navLinks.add(menu);
- DropDownMenuRegistration projects = new DropDownMenuRegistration("gb.projects",
+ DropDownPageMenuNavLink projects = new DropDownPageMenuNavLink("gb.projects",
ProjectPage.class);
projects.menuItems.addAll(getProjectsMenu());
- pages.add(projects);
+ navLinks.add(projects);
}
@Override
diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java b/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java index c404ae61..f04fa78a 100644 --- a/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java +++ b/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java @@ -25,10 +25,10 @@ import org.apache.wicket.markup.repeater.data.ListDataProvider; import com.gitblit.Keys;
import com.gitblit.models.Menu.ParameterMenuItem;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
+import com.gitblit.models.NavLink;
import com.gitblit.models.ProjectModel;
import com.gitblit.wicket.GitBlitWebSession;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.LinkPanel;
@@ -115,10 +115,10 @@ public class ProjectsPage extends RootPage { }
@Override
- protected void addDropDownMenus(List<PageRegistration> pages) {
+ protected void addDropDownMenus(List<NavLink> navLinks) {
PageParameters params = getPageParameters();
- DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
+ DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
ProjectsPage.class);
// preserve time filter option on repository choices
menu.menuItems.addAll(getRepositoryFilterItems(params));
@@ -131,6 +131,6 @@ public class ProjectsPage extends RootPage { menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
}
- pages.add(menu);
+ navLinks.add(menu);
}
}
diff --git a/src/main/java/com/gitblit/wicket/pages/RepositoriesPage.java b/src/main/java/com/gitblit/wicket/pages/RepositoriesPage.java index 41fe057c..a0b15a83 100644 --- a/src/main/java/com/gitblit/wicket/pages/RepositoriesPage.java +++ b/src/main/java/com/gitblit/wicket/pages/RepositoriesPage.java @@ -30,14 +30,14 @@ import org.eclipse.jgit.lib.Constants; import com.gitblit.Keys;
import com.gitblit.models.Menu.ParameterMenuItem;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
+import com.gitblit.models.NavLink;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.MarkdownUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.GitBlitWebSession;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.RepositoriesPanel;
@@ -92,10 +92,10 @@ public class RepositoriesPage extends RootPage { }
@Override
- protected void addDropDownMenus(List<PageRegistration> pages) {
+ protected void addDropDownMenus(List<NavLink> navLinks) {
PageParameters params = getPageParameters();
- DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
+ DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
RepositoriesPage.class);
// preserve time filter option on repository choices
menu.menuItems.addAll(getRepositoryFilterItems(params));
@@ -108,7 +108,7 @@ public class RepositoriesPage extends RootPage { menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
}
- pages.add(menu);
+ navLinks.add(menu);
}
private String readMarkdown(String messageSource, String resource) {
diff --git a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java index 5ea99fd8..165feedf 100644 --- a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -49,6 +48,10 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants;
import com.gitblit.GitBlitException;
import com.gitblit.Keys;
+import com.gitblit.extensions.RepositoryNavLinkExtension;
+import com.gitblit.models.NavLink;
+import com.gitblit.models.NavLink.ExternalNavLink;
+import com.gitblit.models.NavLink.PageNavLink;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RefModel;
import com.gitblit.models.RepositoryModel;
@@ -66,8 +69,6 @@ import com.gitblit.utils.RefLogUtils; import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.GitBlitWebSession;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.OtherPageLink;
import com.gitblit.wicket.SessionlessForm;
import com.gitblit.wicket.TicketsUI;
import com.gitblit.wicket.WicketUtils;
@@ -91,7 +92,6 @@ public abstract class RepositoryPage extends RootPage { private Map<String, SubmoduleModel> submodules;
- private final Map<String, PageRegistration> registeredPages;
private boolean showAdmin;
private boolean isOwner;
@@ -150,12 +150,11 @@ public abstract class RepositoryPage extends RootPage { }
}
- // register the available page links for this page and user
- registeredPages = registerPages();
+ // register the available navigation links for this page and user
+ List<NavLink> navLinks = registerNavLinks();
- // standard page links
- List<PageRegistration> pages = new ArrayList<PageRegistration>(registeredPages.values());
- NavigationPanel navigationPanel = new NavigationPanel("repositoryNavPanel", getRepoNavPageClass(), pages);
+ // standard navigation links
+ NavigationPanel navigationPanel = new NavigationPanel("repositoryNavPanel", getRepoNavPageClass(), navLinks);
add(navigationPanel);
add(new ExternalLink("syndication", SyndicationServlet.asLink(getRequest()
@@ -183,45 +182,56 @@ public abstract class RepositoryPage extends RootPage { return new BugtraqProcessor(app().settings());
}
- private Map<String, PageRegistration> registerPages() {
+ private List<NavLink> registerNavLinks() {
PageParameters params = null;
if (!StringUtils.isEmpty(repositoryName)) {
params = WicketUtils.newRepositoryParameter(repositoryName);
}
- Map<String, PageRegistration> pages = new LinkedHashMap<String, PageRegistration>();
+ List<NavLink> navLinks = new ArrayList<NavLink>();
Repository r = getRepository();
RepositoryModel model = getRepositoryModel();
// standard links
if (RefLogUtils.getRefLogBranch(r) == null) {
- pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));
+ navLinks.add(new PageNavLink("gb.summary", SummaryPage.class, params));
} else {
- pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));
+ navLinks.add(new PageNavLink("gb.summary", SummaryPage.class, params));
// pages.put("overview", new PageRegistration("gb.overview", OverviewPage.class, params));
- pages.put("reflog", new PageRegistration("gb.reflog", ReflogPage.class, params));
+ navLinks.add(new PageNavLink("gb.reflog", ReflogPage.class, params));
}
- pages.put("commits", new PageRegistration("gb.commits", LogPage.class, params));
- pages.put("tree", new PageRegistration("gb.tree", TreePage.class, params));
+ navLinks.add(new PageNavLink("gb.commits", LogPage.class, params));
+ navLinks.add(new PageNavLink("gb.tree", TreePage.class, params));
if (app().tickets().isReady() && (app().tickets().isAcceptingNewTickets(getRepositoryModel()) || app().tickets().hasTickets(getRepositoryModel()))) {
PageParameters tParams = new PageParameters(params);
for (String state : TicketsUI.openStatii) {
tParams.add(Lucene.status.name(), state);
}
- pages.put("tickets", new PageRegistration("gb.tickets", TicketsPage.class, tParams)); + navLinks.add(new PageNavLink("gb.tickets", TicketsPage.class, tParams)); } - pages.put("docs", new PageRegistration("gb.docs", DocsPage.class, params, true));
+ navLinks.add(new PageNavLink("gb.docs", DocsPage.class, params, true));
if (app().settings().getBoolean(Keys.web.allowForking, true)) {
- pages.put("forks", new PageRegistration("gb.forks", ForksPage.class, params, true));
+ navLinks.add(new PageNavLink("gb.forks", ForksPage.class, params, true));
}
- pages.put("compare", new PageRegistration("gb.compare", ComparePage.class, params, true)); + navLinks.add(new PageNavLink("gb.compare", ComparePage.class, params, true)); // conditional links
- // per-repository extra page links
+ // per-repository extra navlinks
if (JGitUtils.getPagesBranch(r) != null) {
- OtherPageLink pagesLink = new OtherPageLink("gb.pages", PagesServlet.asLink(
+ ExternalNavLink pagesLink = new ExternalNavLink("gb.pages", PagesServlet.asLink(
getRequest().getRelativePathPrefixToContextRoot(), repositoryName, null), true);
- pages.put("pages", pagesLink);
+ navLinks.add(pagesLink);
+ }
+
+ UserModel user = UserModel.ANONYMOUS;
+ if (GitBlitWebSession.get().isLoggedIn()) {
+ user = GitBlitWebSession.get().getUser();
+ }
+
+ // add repository nav link extensions
+ List<RepositoryNavLinkExtension> extensions = app().plugins().getExtensions(RepositoryNavLinkExtension.class);
+ for (RepositoryNavLinkExtension ext : extensions) {
+ navLinks.addAll(ext.getNavLinks(user, model));
}
// Conditionally add edit link
@@ -233,9 +243,8 @@ public abstract class RepositoryPage extends RootPage { showAdmin = app().settings().getBoolean(Keys.web.allowAdministration, false);
}
isOwner = GitBlitWebSession.get().isLoggedIn()
- && (model.isOwner(GitBlitWebSession.get()
- .getUsername()));
- return pages;
+ && (model.isOwner(GitBlitWebSession.get().getUsername()));
+ return navLinks;
}
protected boolean allowForkControls() {
diff --git a/src/main/java/com/gitblit/wicket/pages/RootPage.java b/src/main/java/com/gitblit/wicket/pages/RootPage.java index 3003c70e..a2f3a497 100644 --- a/src/main/java/com/gitblit/wicket/pages/RootPage.java +++ b/src/main/java/com/gitblit/wicket/pages/RootPage.java @@ -50,6 +50,7 @@ import org.apache.wicket.protocol.http.WebResponse; import com.gitblit.Constants; import com.gitblit.Keys; +import com.gitblit.extensions.NavLinkExtension; import com.gitblit.extensions.UserMenuExtension; import com.gitblit.models.Menu.ExternalLinkMenuItem; import com.gitblit.models.Menu.MenuDivider; @@ -57,13 +58,14 @@ import com.gitblit.models.Menu.MenuItem; import com.gitblit.models.Menu.PageLinkMenuItem; import com.gitblit.models.Menu.ParameterMenuItem; import com.gitblit.models.Menu.ToggleMenuItem; +import com.gitblit.models.NavLink; +import com.gitblit.models.NavLink.PageNavLink; import com.gitblit.models.RepositoryModel; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.utils.ModelUtils; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebSession; -import com.gitblit.wicket.PageRegistration; import com.gitblit.wicket.SessionlessForm; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.GravatarImage; @@ -174,50 +176,37 @@ public abstract class RootPage extends BasePage { } // navigation links - List<PageRegistration> pages = new ArrayList<PageRegistration>(); + List<NavLink> navLinks = new ArrayList<NavLink>(); if (!authenticateView || (authenticateView && isLoggedIn)) { - pages.add(new PageRegistration(isLoggedIn ? "gb.myDashboard" : "gb.dashboard", MyDashboardPage.class, + navLinks.add(new PageNavLink(isLoggedIn ? "gb.myDashboard" : "gb.dashboard", MyDashboardPage.class, getRootPageParameters())); if (isLoggedIn && app().tickets().isReady()) { - pages.add(new PageRegistration("gb.myTickets", MyTicketsPage.class)); + navLinks.add(new PageNavLink("gb.myTickets", MyTicketsPage.class)); } - pages.add(new PageRegistration("gb.repositories", RepositoriesPage.class, + navLinks.add(new PageNavLink("gb.repositories", RepositoriesPage.class, getRootPageParameters())); - pages.add(new PageRegistration("gb.activity", ActivityPage.class, getRootPageParameters())); + navLinks.add(new PageNavLink("gb.activity", ActivityPage.class, getRootPageParameters())); if (allowLucene) { - pages.add(new PageRegistration("gb.search", LuceneSearchPage.class)); + navLinks.add(new PageNavLink("gb.search", LuceneSearchPage.class)); } - UserModel user = GitBlitWebSession.get().getUser(); - - if (showAdmin) { - // admin dropdown menu - DropDownMenuRegistration adminMenu = new DropDownMenuRegistration("gb.adminMenuItem", MyDashboardPage.class); - - adminMenu.menuItems.add(new PageLinkMenuItem(getString("gb.users"), UsersPage.class)); - - boolean showRegistrations = app().federation().canFederate() - && app().settings().getBoolean(Keys.web.showFederationRegistrations, false); - if (showRegistrations) { - adminMenu.menuItems.add(new PageLinkMenuItem(getString("gb.federation"), FederationPage.class)); - } - - // allow plugins to contribute admin menu items - List<AdminMenuExtension> extensions = app().plugins().getExtensions(AdminMenuExtension.class); - for (AdminMenuExtension ext : extensions) { - adminMenu.menuItems.add(new MenuDivider()); - adminMenu.menuItems.addAll(ext.getMenuItems(user)); - } + if (!authenticateView || (authenticateView && isLoggedIn)) { + addDropDownMenus(navLinks); + } - pages.add(adminMenu); + UserModel user = UserModel.ANONYMOUS; + if (isLoggedIn) { + user = GitBlitWebSession.get().getUser(); } - if (!authenticateView || (authenticateView && isLoggedIn)) { - addDropDownMenus(pages); + // add nav link extensions + List<NavLinkExtension> extensions = app().plugins().getExtensions(NavLinkExtension.class); + for (NavLinkExtension ext : extensions) { + navLinks.addAll(ext.getNavLinks(user)); } } - NavigationPanel navPanel = new NavigationPanel("navPanel", getRootNavPageClass(), pages); + NavigationPanel navPanel = new NavigationPanel("navPanel", getRootNavPageClass(), navLinks); add(navPanel); // display an error message cached from a redirect @@ -309,7 +298,7 @@ public abstract class RootPage extends BasePage { return repositoryModels; } - protected void addDropDownMenus(List<PageRegistration> pages) { + protected void addDropDownMenus(List<NavLink> navLinks) { } diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.java b/src/main/java/com/gitblit/wicket/pages/UserPage.java index 0767621c..6cb791eb 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.java +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.java @@ -30,6 +30,8 @@ import org.eclipse.jgit.lib.PersonIdent; import com.gitblit.Keys;
import com.gitblit.models.Menu.ParameterMenuItem;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
+import com.gitblit.models.NavLink;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
@@ -37,8 +39,6 @@ import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.GravatarImage;
import com.gitblit.wicket.panels.LinkPanel;
@@ -127,10 +127,10 @@ public class UserPage extends RootPage { }
@Override
- protected void addDropDownMenus(List<PageRegistration> pages) {
+ protected void addDropDownMenus(List<NavLink> navLinks) {
PageParameters params = getPageParameters();
- DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
+ DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
UserPage.class);
// preserve time filter option on repository choices
menu.menuItems.addAll(getRepositoryFilterItems(params));
@@ -143,6 +143,6 @@ public class UserPage extends RootPage { menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
}
- pages.add(menu);
+ navLinks.add(menu);
}
}
diff --git a/src/main/java/com/gitblit/wicket/panels/DropDownMenu.java b/src/main/java/com/gitblit/wicket/panels/DropDownMenu.java index f561143d..4e7ae54c 100644 --- a/src/main/java/com/gitblit/wicket/panels/DropDownMenu.java +++ b/src/main/java/com/gitblit/wicket/panels/DropDownMenu.java @@ -21,24 +21,24 @@ import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
-import com.gitblit.models.Menu.MenuDivider;
import com.gitblit.models.Menu.ExternalLinkMenuItem;
+import com.gitblit.models.Menu.MenuDivider;
import com.gitblit.models.Menu.MenuItem;
import com.gitblit.models.Menu.PageLinkMenuItem;
import com.gitblit.models.Menu.ParameterMenuItem;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
+import com.gitblit.models.NavLink.DropDownMenuNavLink;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
import com.gitblit.wicket.WicketUtils;
public class DropDownMenu extends Panel {
private static final long serialVersionUID = 1L;
- public DropDownMenu(String id, String label, final DropDownMenuRegistration menu) {
+ public DropDownMenu(String id, String label, final DropDownPageMenuNavLink menu) {
super(id);
add(new Label("label", label).setRenderBodyOnly(true));
- ListDataProvider<MenuItem> items = new ListDataProvider<MenuItem>(
- menu.menuItems);
+ ListDataProvider<MenuItem> items = new ListDataProvider<MenuItem>(menu.menuItems);
DataView<MenuItem> view = new DataView<MenuItem>("menuItems", items) {
private static final long serialVersionUID = 1L;
@@ -76,4 +76,39 @@ public class DropDownMenu extends Panel { add(view);
setRenderBodyOnly(true);
}
+
+ public DropDownMenu(String id, String label, final DropDownMenuNavLink menu) {
+ super(id);
+
+ add(new Label("label", label).setRenderBodyOnly(true));
+ ListDataProvider<MenuItem> items = new ListDataProvider<MenuItem>(menu.menuItems);
+ DataView<MenuItem> view = new DataView<MenuItem>("menuItems", items) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void populateItem(final Item<MenuItem> item) {
+ MenuItem entry = item.getModelObject();
+ if (entry instanceof PageLinkMenuItem) {
+ // link to another Wicket page
+ PageLinkMenuItem pageLink = (PageLinkMenuItem) entry;
+ item.add(new LinkPanel("menuItem", null, null, pageLink.toString(), pageLink.getPageClass(),
+ pageLink.getPageParameters(), false).setRenderBodyOnly(true));
+ } else if (entry instanceof ExternalLinkMenuItem) {
+ // link to a specified href
+ ExternalLinkMenuItem extLink = (ExternalLinkMenuItem) entry;
+ item.add(new LinkPanel("menuItem", null, extLink.toString(), extLink.getHref(),
+ extLink.openInNewWindow()).setRenderBodyOnly(true));
+ } else if (entry instanceof MenuDivider) {
+ // divider
+ item.add(new Label("menuItem").setRenderBodyOnly(true));
+ WicketUtils.setCssClass(item, "divider");
+ } else {
+ throw new IllegalArgumentException(String.format("Unexpected menuitem type %s",
+ entry.getClass().getSimpleName()));
+ }
+ }
+ };
+ add(view);
+ setRenderBodyOnly(true);
+ }
}
\ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/panels/NavigationPanel.java b/src/main/java/com/gitblit/wicket/panels/NavigationPanel.java index 7db29fa2..2bc92f4c 100644 --- a/src/main/java/com/gitblit/wicket/panels/NavigationPanel.java +++ b/src/main/java/com/gitblit/wicket/panels/NavigationPanel.java @@ -23,9 +23,11 @@ import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
-import com.gitblit.wicket.PageRegistration;
-import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
-import com.gitblit.wicket.PageRegistration.OtherPageLink;
+import com.gitblit.models.NavLink;
+import com.gitblit.models.NavLink.DropDownMenuNavLink;
+import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
+import com.gitblit.models.NavLink.ExternalNavLink;
+import com.gitblit.models.NavLink.PageNavLink;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.pages.BasePage;
@@ -34,52 +36,59 @@ public class NavigationPanel extends Panel { private static final long serialVersionUID = 1L;
public NavigationPanel(String id, final Class<? extends BasePage> pageClass,
- List<PageRegistration> registeredPages) {
+ List<NavLink> navLinks) {
super(id);
- ListDataProvider<PageRegistration> refsDp = new ListDataProvider<PageRegistration>(
- registeredPages);
- DataView<PageRegistration> refsView = new DataView<PageRegistration>("navLink", refsDp) {
+ ListDataProvider<NavLink> refsDp = new ListDataProvider<NavLink>(navLinks);
+ DataView<NavLink> linksView = new DataView<NavLink>("navLink", refsDp) {
private static final long serialVersionUID = 1L;
@Override
- public void populateItem(final Item<PageRegistration> item) {
- PageRegistration entry = item.getModelObject();
- String linkText = entry.translationKey;
+ public void populateItem(final Item<NavLink> item) {
+ NavLink navLink = item.getModelObject();
+ String linkText = navLink.translationKey;
try {
// try to lookup translation key
- linkText = getString(entry.translationKey);
+ linkText = getString(navLink.translationKey);
} catch (Exception e) {
}
- if (entry.hiddenPhone) {
+ if (navLink.hiddenPhone) {
WicketUtils.setCssClass(item, "hidden-phone");
}
- if (entry instanceof OtherPageLink) {
+ if (navLink instanceof ExternalNavLink) {
// other link
- OtherPageLink link = (OtherPageLink) entry;
+ ExternalNavLink link = (ExternalNavLink) navLink;
Component c = new LinkPanel("link", null, linkText, link.url);
c.setRenderBodyOnly(true);
item.add(c);
- } else if (entry instanceof DropDownMenuRegistration) {
+ } else if (navLink instanceof DropDownPageMenuNavLink) {
// drop down menu
- DropDownMenuRegistration reg = (DropDownMenuRegistration) entry;
+ DropDownPageMenuNavLink reg = (DropDownPageMenuNavLink) navLink;
Component c = new DropDownMenu("link", linkText, reg);
c.setRenderBodyOnly(true);
item.add(c);
WicketUtils.setCssClass(item, "dropdown");
- } else {
+ } else if (navLink instanceof DropDownMenuNavLink) {
+ // drop down menu
+ DropDownMenuNavLink reg = (DropDownMenuNavLink) navLink;
+ Component c = new DropDownMenu("link", linkText, reg);
+ c.setRenderBodyOnly(true);
+ item.add(c);
+ WicketUtils.setCssClass(item, "dropdown");
+ } else if (navLink instanceof PageNavLink) {
+ PageNavLink reg = (PageNavLink) navLink;
// standard page link
Component c = new LinkPanel("link", null, linkText,
- entry.pageClass, entry.params);
+ reg.pageClass, reg.params);
c.setRenderBodyOnly(true);
- if (entry.pageClass.equals(pageClass)) {
+ if (reg.pageClass.equals(pageClass)) {
WicketUtils.setCssClass(item, "active");
}
item.add(c);
}
}
};
- add(refsView);
+ add(linksView);
}
}
\ No newline at end of file |