Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/AbstractBasePage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/AbstractBasePage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/AbstractBasePage.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/AbstractBasePage.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,181 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.navbar.Navbar.ComponentPosition.LEFT;
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.navbar.NavbarComponents.transform;
+
+import java.util.List;
+
+import org.apache.nutch.webui.model.NutchInstance;
+import org.apache.nutch.webui.pages.crawls.CrawlsPage;
+import org.apache.nutch.webui.pages.instances.InstancesPage;
+import org.apache.nutch.webui.pages.menu.VerticalMenu;
+import org.apache.nutch.webui.pages.seed.SeedListsPage;
+import org.apache.nutch.webui.pages.settings.SettingsPage;
+import org.apache.nutch.webui.service.NutchInstanceService;
+import org.apache.nutch.webui.service.NutchService;
+import org.apache.wicket.Component;
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.GenericWebPage;
+import org.apache.wicket.markup.html.link.AbstractLink;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.button.dropdown.DropDownButton;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.button.dropdown.MenuBookmarkablePageLink;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.button.dropdown.MenuDivider;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.navbar.Navbar.ComponentPosition;
+import de.agilecoders.wicket.core.markup.html.bootstrap.navbar.Navbar.Position;
+import de.agilecoders.wicket.core.markup.html.bootstrap.navbar.NavbarButton;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.navbar.NavbarComponents;
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.navbar.NavbarDropDownButton;
+import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesomeIconType;
+
+public abstract class AbstractBasePage<T> extends GenericWebPage<T> {
+  @SpringBean
+  private NutchService service;
+
+  @SpringBean
+  private NutchInstanceService instanceService;
+
+  private VerticalMenu navbar;
+
+  protected IModel<NutchInstance> currentInstance = new InstanceModel();
+
+  public AbstractBasePage() {
+    navbar = new VerticalMenu("navigation");
+    navbar.brandName(Model.of("Apache Nutch GUI"));
+    navbar.setInverted(true);
+    navbar.setPosition(Position.TOP);
+    add(navbar);
+
+    addMenuItem(DashboardPage.class, "navbar.menu.dashboard",
+        FontAwesomeIconType.dashboard);
+    addMenuItem(StatisticsPage.class, "navbar.menu.statistics",
+        FontAwesomeIconType.bar_chart_o);
+    addMenuItem(InstancesPage.class, "navbar.menu.instances",
+        FontAwesomeIconType.gears);
+    addMenuItem(SettingsPage.class, "navbar.menu.settings",
+        FontAwesomeIconType.wrench);
+    addMenuItem(CrawlsPage.class, "navbar.menu.crawls",
+        FontAwesomeIconType.refresh);
+    addMenuItem(SchedulingPage.class, "navbar.menu.scheduling",
+        FontAwesomeIconType.clock_o);
+    addMenuItem(SearchPage.class, "navbar.menu.search",
+        FontAwesomeIconType.search);
+    addMenuItem(SeedListsPage.class, "navbar.menu.seedLists",
+        FontAwesomeIconType.file);
+
+    navbar.addComponents(transform(ComponentPosition.RIGHT,
+        addInstancesMenuMenu()));
+    navbar.addComponents(transform(ComponentPosition.RIGHT, addUserMenu()));
+
+    add(new NotificationPanel("globalNotificationPanel"));
+
+    if (currentInstance.getObject() == null && !(this instanceof 
InstancesPage)) {
+      getSession().error("No running instances found!");
+      setResponsePage(InstancesPage.class);
+    }
+  }
+
+  protected Component addUserMenu() {
+    DropDownButton userMenu = new NavbarDropDownButton(Model.of("Username")) {
+      @Override
+      protected List<AbstractLink> newSubMenuButtons(final String 
buttonMarkupId) {
+        List<AbstractLink> subMenu = Lists.newArrayList();
+        subMenu.add(new MenuBookmarkablePageLink<Void>(UserSettingsPage.class,
+            new ResourceModel("navbar.userMenu.settings"))
+            .setIconType(FontAwesomeIconType.gear));
+        subMenu.add(new MenuDivider());
+        subMenu.add(new MenuBookmarkablePageLink<Void>(LogOutPage.class,
+            new ResourceModel("navbar.userMenu.logout"))
+            .setIconType(FontAwesomeIconType.power_off));
+        return subMenu;
+      }
+    }.setIconType(FontAwesomeIconType.user);
+    return userMenu;
+  }
+
+  protected Component addInstancesMenuMenu() {
+    IModel<String> instanceName = PropertyModel.of(currentInstance, "name");
+    DropDownButton instancesMenu = new NavbarDropDownButton(instanceName) {
+
+      @Override
+      protected List<AbstractLink> newSubMenuButtons(String buttonMarkupId) {
+        List<NutchInstance> instances = instanceService.getInstances();
+        List<AbstractLink> subMenu = Lists.newArrayList();
+        for (NutchInstance instance : instances) {
+          subMenu.add(new Link<NutchInstance>(buttonMarkupId, Model
+              .of(instance)) {
+            @Override
+            public void onClick() {
+              currentInstance.setObject(getModelObject());
+              setResponsePage(DashboardPage.class);
+            }
+          }.setBody(Model.of(instance.getName())));
+        }
+        return subMenu;
+      }
+    }.setIconType(FontAwesomeIconType.gears);
+
+    return instancesMenu;
+  }
+
+  private <P extends Page> void addMenuItem(Class<P> page, String label,
+      IconType icon) {
+    Component button = new NavbarButton<Void>(page, Model.of(getString(label)))
+        .setIconType(icon);
+    navbar.addComponents(NavbarComponents.transform(LEFT, button));
+  }
+
+  protected NutchInstance getCurrentInstance() {
+    return currentInstance.getObject();
+  }
+
+  private class InstanceModel extends LoadableDetachableModel<NutchInstance> {
+
+    @Override
+    public void setObject(NutchInstance instance) {
+      super.setObject(instance);
+      getSession().setAttribute("instanceId", instance.getId());
+    }
+
+    @Override
+    protected NutchInstance load() {
+      Long instanceId = (Long) getSession().getAttribute("instanceId");
+      if (instanceId == null) {
+        return getFirstInstance();
+      }
+      return instanceService.getInstance(instanceId);
+    }
+
+    private NutchInstance getFirstInstance() {
+      return Iterables.getFirst(instanceService.getInstances(), null);
+    }
+  }
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.html?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.html (added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.html Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,52 @@
+<!-- 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. -->
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+<meta charset="utf-8" />
+<title>Wicket extend</title>
+</head>
+
+<body>
+       <wicket:extend>
+               <h2>
+                       <wicket:message 
key="navbar.menu.dashboard">Instances</wicket:message>
+               </h2>
+               <div class="row">
+                       <div class="col-lg-3">
+                               <div class="panel panel-info">
+                                       <div wicket:id="panel" 
class="panel-heading">
+                                               <div class="row">
+                                                       <div class="col-xs-6">
+                                                               <i class="fa 
fa-gears fa-5x"></i>
+                                                       </div>
+                                                       <div class="col-xs-6 
text-right">
+                                                               <p 
class="announcement-heading" wicket:id="jobsRunning">2</p>
+                                                               <p 
class="announcement-text">Jobs running</p>
+                                                       </div>
+                                               </div>
+                                       </div>
+                                       <a href="#non-existing-id" 
wicket:id="viewInstances">
+                                               <div class="panel-footer 
announcement-bottom">
+                                                       <div class="row">
+                                                               <div 
class="col-xs-6">View instances</div>
+                                                               <div 
class="col-xs-6 text-right">
+                                                                       <i 
class="fa fa-arrow-circle-right"></i>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </a>
+                               </div>
+                       </div>
+               </div>
+       </wicket:extend>
+</body>
+</html>

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.java (added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/DashboardPage.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,56 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+import org.apache.nutch.webui.client.model.NutchStatus;
+import org.apache.nutch.webui.model.NutchInstance;
+import org.apache.nutch.webui.pages.instances.InstancesPage;
+import org.apache.nutch.webui.service.NutchService;
+import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.apache.wicket.util.time.Duration;
+
+public class DashboardPage extends AbstractBasePage<Object> {
+  @SpringBean
+  private NutchService nutchService;
+
+  private WebMarkupContainer panel;
+
+  public DashboardPage() {
+    panel = new WebMarkupContainer("panel");
+    panel.setOutputMarkupId(true);
+    panel.add(new AjaxSelfUpdatingTimerBehavior(Duration.ONE_SECOND));
+    panel.add(new Label("jobsRunning", new JobsModel()));
+    add(panel);
+    add(new BookmarkablePageLink<Void>("viewInstances", InstancesPage.class));
+
+  }
+
+  private class JobsModel extends LoadableDetachableModel<Integer> {
+    @Override
+    protected Integer load() {
+      NutchInstance currentInstance = getCurrentInstance();
+      Long id = currentInstance.getId();
+      NutchStatus nutchStatus = nutchService.getNutchStatus(id);
+      return nutchStatus.getRunningJobs().size();
+    }
+  }
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/LogOutPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/LogOutPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/LogOutPage.java (added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/LogOutPage.java Mon Sep 
28 18:58:33 2015
@@ -0,0 +1,21 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+public class LogOutPage extends AbstractBasePage {
+
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/SchedulingPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/SchedulingPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/SchedulingPage.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/SchedulingPage.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,21 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+public class SchedulingPage extends AbstractBasePage {
+
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/SearchPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/SearchPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/SearchPage.java (added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/SearchPage.java Mon Sep 
28 18:58:33 2015
@@ -0,0 +1,21 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+public class SearchPage extends AbstractBasePage {
+
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/StatisticsPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/StatisticsPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/StatisticsPage.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/StatisticsPage.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,21 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+public class StatisticsPage extends AbstractBasePage {
+
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/UrlsUploadPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/UrlsUploadPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/UrlsUploadPage.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/UrlsUploadPage.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,21 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+public class UrlsUploadPage extends AbstractBasePage {
+
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/UserSettingsPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/UserSettingsPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/UserSettingsPage.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/UserSettingsPage.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,21 @@
+/**
+ * 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 org.apache.nutch.webui.pages;
+
+public class UserSettingsPage extends AbstractBasePage {
+
+}

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/NutchUiCssReference.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/NutchUiCssReference.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/NutchUiCssReference.java
 (added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/NutchUiCssReference.java
 Mon Sep 28 18:58:33 2015
@@ -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 org.apache.nutch.webui.pages.assets;
+
+import org.apache.wicket.request.resource.CssResourceReference;
+
+public class NutchUiCssReference extends CssResourceReference {
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * Singleton instance of this reference
+   */
+  private static final NutchUiCssReference INSTANCE = new 
NutchUiCssReference();
+
+  public static NutchUiCssReference instance() {
+    return INSTANCE;
+  }
+
+  /**
+   * Private constructor.
+   */
+  private NutchUiCssReference() {
+    super(NutchUiCssReference.class, "nutch-style.css");
+  }
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/nutch-style.css
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/nutch-style.css?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/nutch-style.css 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/assets/nutch-style.css 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,149 @@
+/**
+ * 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.
+ */
+@CHARSET "UTF-8";
+
+body {
+       margin-top: 50px;
+}
+
+#wrapper {
+       padding-left: 0;
+}
+
+#page-wrapper {
+       width: 100%;
+       padding: 5px 15px;
+}
+
+/* Nav Messages */
+.messages-dropdown .dropdown-menu .message-preview .avatar,.messages-dropdown 
.dropdown-menu .message-preview .name,.messages-dropdown .dropdown-menu 
.message-preview .message,.messages-dropdown .dropdown-menu .message-preview 
.time
+       {
+       display: block;
+}
+
+.messages-dropdown .dropdown-menu .message-preview .avatar {
+       float: left;
+       margin-right: 15px;
+}
+
+.messages-dropdown .dropdown-menu .message-preview .name {
+       font-weight: bold;
+}
+
+.messages-dropdown .dropdown-menu .message-preview .message {
+       font-size: 12px;
+}
+
+.messages-dropdown .dropdown-menu .message-preview .time {
+       font-size: 12px;
+}
+
+/* Nav Announcements */
+.announcement-heading {
+       font-size: 50px;
+       margin: 0;
+}
+
+.announcement-text {
+       margin: 0;
+}
+
+/* Table Headers */
+table.tablesorter thead {
+       cursor: pointer;
+}
+
+table.tablesorter thead tr th:hover {
+       background-color: #f5f5f5;
+}
+
+/* Flot Chart Containers */
+.flot-chart {
+       display: block;
+       height: 400px;
+}
+
+.flot-chart-content {
+       width: 100%;
+       height: 100%;
+}
+
+/* Edit Below to Customize Widths > 768px */
+@media ( min-width :768px) {
+       /* Wrappers */
+       #wrapper {
+               padding-left: 225px;
+       }
+       #page-wrapper {
+               padding: 15px 25px;
+       }
+
+       /* Side Nav */
+       .side-nav {
+               margin-left: -225px;
+               left: 225px;
+               width: 225px;
+               position: fixed;
+               top: 50px;
+               height: 100%;
+               border-radius: 0;
+               border: none;
+               background-color: #222222;
+               overflow-y: auto;
+       }
+
+       /* Bootstrap Default Overrides - Customized Dropdowns for the Side Nav 
*/
+       .side-nav>li.dropdown>ul.dropdown-menu {
+               position: relative;
+               min-width: 225px;
+               margin: 0;
+               padding: 0;
+               border: none;
+               border-radius: 0;
+               background-color: transparent;
+               box-shadow: none;
+               -webkit-box-shadow: none;
+       }
+       .side-nav>li.dropdown>ul.dropdown-menu>li>a {
+               color: #999999;
+               padding: 15px 15px 15px 25px;
+       }
+       
.side-nav>li.dropdown>ul.dropdown-menu>li>a:hover,.side-nav>li.dropdown>ul.dropdown-menu>li>a.active,.side-nav>li.dropdown>ul.dropdown-menu>li>a:focus
+               {
+               color: #fff;
+               background-color: #080808;
+       }
+       .side-nav>li>a {
+               width: 225px;
+       }
+       .navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse 
.navbar-nav>li>a:focus
+               {
+               background-color: #080808;
+       }
+
+       /* Nav Messages */
+       .messages-dropdown .dropdown-menu {
+               min-width: 300px;
+       }
+       .messages-dropdown .dropdown-menu li a {
+               white-space: normal;
+       }
+       .navbar-collapse {
+               padding-left: 15px !important;
+               padding-right: 15px !important;
+       }
+}
\ No newline at end of file

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabel.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabel.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabel.java
 (added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabel.java
 Mon Sep 28 18:58:33 2015
@@ -0,0 +1,71 @@
+/**
+ * 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 org.apache.nutch.webui.pages.components;
+
+import java.util.Map;
+
+import org.apache.wicket.markup.html.basic.EnumLabel;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.IModel;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelBehavior;
+import de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType;
+
+/**
+ * Label which renders connection status as bootstrap label
+ * 
+ * @author feodor
+ * 
+ */
+public class ColorEnumLabel<E extends Enum<E>> extends EnumLabel<E> {
+  private Map<E, LabelType> labelTypeMap;
+
+  ColorEnumLabel(String id, IModel<E> model, Map<E, LabelType> labelTypeMap) {
+    super(id, model);
+    this.labelTypeMap = labelTypeMap;
+  }
+
+  @Override
+  protected void onInitialize() {
+    super.onInitialize();
+    setOutputMarkupId(true);
+    add(new LabelBehavior(new EnumCssModel(getModel())));
+  }
+
+  private class EnumCssModel extends AbstractReadOnlyModel<LabelType> {
+    private IModel<E> model;
+
+    public EnumCssModel(IModel<E> model) {
+      this.model = model;
+    }
+
+    @Override
+    public LabelType getObject() {
+      LabelType labelType = labelTypeMap.get(model.getObject());
+      if (labelType == null) {
+        return LabelType.Default;
+      }
+      return labelType;
+    }
+  }
+
+  public static <E extends Enum<E>> ColorEnumLabelBuilder<E> getBuilder(
+      String id) {
+    return new ColorEnumLabelBuilder<E>(id);
+  }
+
+}

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabelBuilder.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabelBuilder.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabelBuilder.java
 (added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/ColorEnumLabelBuilder.java
 Mon Sep 28 18:58:33 2015
@@ -0,0 +1,49 @@
+/**
+ * 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 org.apache.nutch.webui.pages.components;
+
+import java.util.Map;
+
+import org.apache.wicket.model.IModel;
+
+import com.google.common.collect.Maps;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType;
+
+public class ColorEnumLabelBuilder<E extends Enum<E>> {
+  private Map<E, LabelType> labelTypeMap = Maps.newHashMap();
+  private IModel<E> model;
+  private String id;
+
+  public ColorEnumLabelBuilder(String id) {
+    this.id = id;
+  }
+
+  public ColorEnumLabelBuilder<E> withModel(IModel<E> model) {
+    this.model = model;
+    return this;
+  }
+
+  public ColorEnumLabelBuilder<E> withEnumColor(E e, LabelType type) {
+    labelTypeMap.put(e, type);
+    return this;
+  }
+
+  public ColorEnumLabel<E> build() {
+    return new ColorEnumLabel<E>(id, model, labelTypeMap);
+  }
+}
\ No newline at end of file

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/CpmIteratorAdapter.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/components/CpmIteratorAdapter.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/CpmIteratorAdapter.java
 (added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/components/CpmIteratorAdapter.java
 Mon Sep 28 18:58:33 2015
@@ -0,0 +1,41 @@
+/**
+ * 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 org.apache.nutch.webui.pages.components;
+
+import org.apache.wicket.markup.repeater.util.ModelIteratorAdapter;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+
+/**
+ * This is iterator adapter, which wraps iterable items with
+ * CompoundPropertyModel.
+ * 
+ * @author feodor
+ * 
+ * @param <T>
+ */
+public class CpmIteratorAdapter<T> extends ModelIteratorAdapter<T> {
+  public CpmIteratorAdapter(Iterable<T> iterable) {
+    super(iterable);
+  }
+
+  @Override
+  protected IModel<T> model(T object) {
+    return new CompoundPropertyModel<T>(object);
+  }
+
+}
\ No newline at end of file

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.html?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.html 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.html 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,58 @@
+<!-- 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. -->
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+<meta charset="utf-8" />
+<title>Wicket extend</title>
+</head>
+
+<body>
+       <wicket:extend>
+               <div wicket:id="notificationPanel"></div>
+
+               <form class="form-horizontal" wicket:id="crawlForm">
+                       <div class="form-group">
+                               <label for="inputEmail" class="control-label 
col-xs-2">Crawl id</label>
+                               <div class="col-xs-10">
+                                       <span 
wicket:id="crawlId">123-1321-123</span>
+                               </div>
+                       </div>
+                       <div class="form-group">
+                               <label for="seedDir" class="control-label 
col-xs-2">Crawl name</label>
+                               <div class="col-xs-10">
+                                       <input class="form-control" 
id="seedDir" wicket:id="crawlName" placeholder="Crawl name">
+                               </div>
+                       </div>
+                       <div class="form-group">
+                               <label for="seedDir" class="control-label 
col-xs-2">Seed list</label>
+                               <div class="col-xs-10">
+                                       <select wicket:id="seedList">
+                                               <option>Google list</option>
+                                               <option>Yahoo list</option>
+                                       </select>
+                               </div>
+                       </div>
+
+                       <div class="form-group">
+                               <label for="numberOfRounds" 
class="control-label col-xs-2">Rounds</label>
+                               <div class="col-xs-10">
+                                       <select wicket:id="numberOfRounds">
+                                               <option>1</option>
+                                               <option>2</option>
+                                       </select>
+                               </div>
+                       </div>
+               </form>
+
+       </wicket:extend>
+</body>
+</html>

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlPanel.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,98 @@
+/**
+ * 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 org.apache.nutch.webui.pages.crawls;
+
+import java.util.List;
+
+import org.apache.nutch.webui.client.model.Crawl;
+import org.apache.nutch.webui.model.SeedList;
+import org.apache.nutch.webui.service.CrawlService;
+import org.apache.nutch.webui.service.SeedListService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+import com.google.common.collect.Lists;
+
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.form.BootstrapForm;
+
+public class CrawlPanel extends Modal {
+  private static final int MAX_ROUNDS = 10;
+
+  private BootstrapForm<Crawl> form;
+
+  @SpringBean
+  private CrawlService crawlService;
+
+  @SpringBean
+  private SeedListService seedListService;
+
+  private NotificationPanel notificationPanel;
+
+  public CrawlPanel(String markupId) {
+    super(markupId);
+    header(Model.of("Crawl"));
+
+    notificationPanel = new NotificationPanel("notificationPanel");
+    notificationPanel.setOutputMarkupId(true);
+    add(notificationPanel);
+
+    form = new BootstrapForm<Crawl>("crawlForm");
+    form.add(new Label("crawlId"));
+    form.add(new TextField<String>("crawlName").setRequired(true));
+
+    form.add(new DropDownChoice<Integer>("numberOfRounds", 
getNumbersOfRounds()));
+    form.add(new DropDownChoice<SeedList>("seedList",
+        seedListService.findAll(), new ChoiceRenderer<SeedList>("name"))
+        .setRequired(true));
+
+    addButton(new AjaxSubmitLink("button", form) {
+      @Override
+      protected void onSubmit(AjaxRequestTarget target, Form<?> ajaxForm) {
+        crawlService.saveCrawl(form.getModelObject());
+        target.add(this.getPage());
+      }
+
+      protected void onError(AjaxRequestTarget target, Form<?> form) {
+        target.add(notificationPanel);
+      };
+    }.setBody(Model.of("Save")));
+    add(form);
+  }
+
+  public void setModel(IModel<Crawl> model) {
+    form.setModel(model);
+  }
+
+  private List<Integer> getNumbersOfRounds() {
+    List<Integer> numbers = Lists.newArrayList();
+    for (int i = 1; i <= MAX_ROUNDS; i++) {
+      numbers.add(i);
+    }
+    return numbers;
+  }
+
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.html?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.html 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.html 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,90 @@
+<!-- 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. -->
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+<meta charset="utf-8" />
+<title>Wicket extend</title>
+</head>
+
+<body>
+       <wicket:extend>
+               <h2>
+                       <wicket:message 
key="navbar.menu.crawls">Crawls</wicket:message>
+               </h2>
+
+               <div class="row">
+                       <div class="col-lg-8">
+                               <div class="row">
+                                       <div class="col-lg-8 col-md-offset-10">
+                                               <button class="btn btn-success 
btn-default" wicket:id="newCrawl">
+                                                       <i class="fa 
fa-plus"></i> Add new crawl
+                                               </button>
+                                       </div>
+                               </div>
+                               <table class="table table-hover table-striped 
tablesorter">
+                                       <thead>
+                                               <tr>
+                                                       <th class="header 
col-md-2">Crawl name</th>
+                                                       <th class="header 
col-md-2">Seed list</th>
+                                                       <th class="header 
col-md-2">Status</th>
+                                                       <th class="header 
col-md-2">Progress</th>
+                                                       <th></th>
+                                               </tr>
+                                       </thead>
+
+                                       <tbody wicket:id="crawlsTable">
+                                               <tr wicket:id="crawls">
+                                                       <td>
+                                                               <a href="#" 
data-toggle="modal" data-target="#crawlInfo" wicket:id="edit">
+                                                                       <span 
wicket:id="crawlName">Crawl name</span>
+                                                               </a>
+                                                       </td>
+                                                       <td>
+                                                               <span 
wicket:id="seedList.name">Google list</span>
+                                                       </td>
+                                                       <td>
+                                                               <span 
wicket:id="status" class="label">Finished</span>
+                                                       </td>
+                                                       <td>
+                                                               <span 
wicket:id="progress">50</span>
+                                                               %
+
+                                                       </td>
+
+                                                       <td>
+                                                               <button 
class="btn btn-sm btn-default" type="button" wicket:id="start">
+                                                                       <span 
class="fa fa-play"></span>
+                                                               </button>
+                                                               <button 
class="btn btn-sm btn-danger" type="button" wicket:id="delete">
+                                                                       <span 
class="fa fa-trash-o"></span>
+                                                               </button>
+                                                       </td>
+                                               </tr>
+                                       </tbody>
+                               </table>
+                               <div wicket:id="crawl"></div>
+                       </div>
+                       <div class="col-lg-4">
+                               <div class="panel panel-primary">
+                                       <div class="panel-heading">
+                                               <h3 
class="panel-title">Help</h3>
+                                       </div>
+                                       <div class="panel-body">
+                                               <p>Some help about crawling</p>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+               <!--row-->
+       </wicket:extend>
+</body>
+</html>

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/crawls/CrawlsPage.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,139 @@
+/**
+ * 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 org.apache.nutch.webui.pages.crawls;
+
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType.Danger;
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType.Default;
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType.Info;
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType.Success;
+import static org.apache.nutch.webui.client.model.Crawl.CrawlStatus.CRAWLING;
+import static org.apache.nutch.webui.client.model.Crawl.CrawlStatus.ERROR;
+import static org.apache.nutch.webui.client.model.Crawl.CrawlStatus.FINISHED;
+import static org.apache.nutch.webui.client.model.Crawl.CrawlStatus.NEW;
+
+import java.util.Iterator;
+
+import org.apache.nutch.webui.client.model.Crawl;
+import org.apache.nutch.webui.client.model.Crawl.CrawlStatus;
+import org.apache.nutch.webui.pages.AbstractBasePage;
+import org.apache.nutch.webui.pages.components.ColorEnumLabelBuilder;
+import org.apache.nutch.webui.pages.components.CpmIteratorAdapter;
+import org.apache.nutch.webui.service.CrawlService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.EnumLabel;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.markup.repeater.RefreshingView;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.apache.wicket.util.time.Duration;
+
+/**
+ * This page is for crawls management
+ * 
+ * @author feodor
+ * 
+ */
+public class CrawlsPage extends AbstractBasePage<Void> {
+
+  private static final Duration UPDATE_TIMEOUT = Duration.seconds(2);
+
+  @SpringBean
+  private CrawlService crawlService;
+
+  private WebMarkupContainer crawlsTable;
+  private CrawlPanel crawlPanel;
+
+  public CrawlsPage() {
+    crawlsTable = new WebMarkupContainer("crawlsTable");
+    crawlsTable.setOutputMarkupId(true);
+    crawlsTable.add(new AjaxSelfUpdatingTimerBehavior(UPDATE_TIMEOUT));
+
+    RefreshingView<Crawl> crawls = new RefreshingView<Crawl>("crawls") {
+
+      @Override
+      protected Iterator<IModel<Crawl>> getItemModels() {
+        return new CpmIteratorAdapter<Crawl>(crawlService.getCrawls());
+      }
+
+      @Override
+      protected void populateItem(Item<Crawl> item) {
+        populateCrawlRow(item);
+      }
+    };
+
+    crawlsTable.add(crawls);
+    add(crawlsTable);
+
+    crawlPanel = new CrawlPanel("crawl");
+    add(crawlPanel);
+
+    add(new AjaxLink<Crawl>("newCrawl") {
+      @Override
+      public void onClick(AjaxRequestTarget target) {
+        editCrawl(target, new CompoundPropertyModel<Crawl>(createNewCrawl()));
+      }
+    });
+  }
+
+  private void populateCrawlRow(Item<Crawl> item) {
+    item.add(new AjaxLink<Crawl>("edit", item.getModel()) {
+      @Override
+      public void onClick(AjaxRequestTarget target) {
+        editCrawl(target, getModel());
+      }
+    }.add(new Label("crawlName")));
+    item.add(new Label("seedList.name"));
+
+    item.add(new Label("progress"));
+    item.add(createStatusLabel());
+    item.add(new Link<Crawl>("start", item.getModel()) {
+      @Override
+      public void onClick() {
+        crawlService.startCrawl(getModelObject().getId(), 
getCurrentInstance());
+      }
+    });
+
+    item.add(new Link<Crawl>("delete", item.getModel()) {
+      @Override
+      public void onClick() {
+        crawlService.deleteCrawl(getModelObject().getId());
+      }
+    });
+  }
+
+  private void editCrawl(AjaxRequestTarget target, IModel<Crawl> model) {
+    crawlPanel.setModel(model);
+    target.add(crawlPanel);
+    crawlPanel.appendShowDialogJavaScript(target);
+  }
+
+  private Crawl createNewCrawl() {
+    return new Crawl();
+  }
+
+  private EnumLabel<CrawlStatus> createStatusLabel() {
+    return new ColorEnumLabelBuilder<CrawlStatus>("status")
+        .withEnumColor(NEW, Default).withEnumColor(ERROR, Danger)
+        .withEnumColor(FINISHED, Success).withEnumColor(CRAWLING, 
Info).build();
+  }
+}

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.html?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.html 
(added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.html 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+       <wicket:extend>
+               <div wicket:id="notificationPanel"></div>
+               <form class="form-horizontal" wicket:id="instanceForm">
+                       <div class="form-group">
+                               <label class="control-label 
col-xs-2"><wicket:message key="instances.label.name">Instance 
name</wicket:message></label>
+                               <div class="col-xs-10">
+                                       <input class="form-control" 
wicket:id="name" placeholder="Localhost instance">
+                               </div>
+                       </div>
+                       <div class="form-group">
+                               <label class="control-label 
col-xs-2"><wicket:message 
key="instances.label.hostname">Host</wicket:message></label>
+                               <div class="col-xs-10">
+                                       <input class="form-control" 
wicket:id="host" placeholder="http://localhost:8080";>
+                               </div>
+                       </div>
+
+                       <div class="form-group">
+                               <label class="control-label 
col-xs-2"><wicket:message 
key="instances.label.port">Port</wicket:message></label>
+                               <div class="col-xs-10">
+                                       <input class="form-control" 
wicket:id="port" placeholder="http://localhost:8080";>
+                               </div>
+                       </div>
+                       
+                       <div class="form-group">
+                               <label class="control-label 
col-xs-2"><wicket:message 
key="instances.label.username">Username</wicket:message></label>
+                               <div class="col-xs-10">
+                                       <input class="form-control" 
wicket:id="username" placeholder="">
+                               </div>
+                       </div>
+                       <div class="form-group">
+                               <label class="control-label 
col-xs-2"><wicket:message 
key="instances.label.password">Password</wicket:message></label>
+                               <div class="col-xs-10">
+                                       <input class="form-control" 
type="password" wicket:id="password" placeholder="">
+                               </div>
+                       </div>
+               </form>
+       </wicket:extend>
+</body>
+</html>
\ No newline at end of file

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.java 
(added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancePanel.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,62 @@
+package org.apache.nutch.webui.pages.instances;
+
+import org.apache.nutch.webui.model.NutchInstance;
+import org.apache.nutch.webui.service.NutchInstanceService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import de.agilecoders.wicket.core.markup.html.bootstrap.form.BootstrapForm;
+
+public class InstancePanel extends Modal {
+
+  private BootstrapForm<NutchInstance> form;
+
+  private NotificationPanel notificationPanel;
+
+  @SpringBean
+  private NutchInstanceService instanceService;
+
+  public InstancePanel(String markupId) {
+    super(markupId);
+    header(Model.of("Instance"));
+
+    notificationPanel = new NotificationPanel("notificationPanel");
+    notificationPanel.setOutputMarkupId(true);
+    add(notificationPanel);
+
+    form = new BootstrapForm<NutchInstance>("instanceForm");
+    form.add(new TextField<String>("name").setRequired(true));
+    form.add(new TextField<String>("host").setRequired(true));
+    form.add(new TextField<Integer>("port").setRequired(true));
+    form.add(new TextField<String>("username"));
+    form.add(new PasswordTextField("password").setResetPassword(false)
+        .setRequired(false));
+
+    addButton(new AjaxSubmitLink("button", form) {
+      @Override
+      protected void onSubmit(AjaxRequestTarget target, Form<?> ajaxForm) {
+        instanceService.saveInstance(form.getModelObject());
+        target.add(this.getPage());
+
+      }
+
+      protected void onError(AjaxRequestTarget target, Form<?> form) {
+        target.add(notificationPanel);
+      };
+    }.setBody(Model.of("Save")));
+    add(form);
+  }
+
+  public void setModel(IModel<NutchInstance> model) {
+    form.setModel(model);
+  }
+
+}

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.html?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.html 
(added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.html 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>Instances</title>
+</head>
+<body>
+       <wicket:extend>
+               <h2>
+                       <wicket:message 
key="navbar.menu.instances">Instances</wicket:message>
+               </h2>
+               <div class="row">
+                       <div class="col-lg-8">
+                               <table class="table table-hover table-striped 
tablesorter">
+                                       <thead>
+                                               <tr>
+                                                       <th class="header 
col-md-2"><wicket:message key="instances.header.name">Name</wicket:message></th>
+                                                       <th class="header 
col-md-2"><wicket:message 
key="instances.header.hostname">Host</wicket:message></th>
+                                                       <th class="header 
col-md-2"><wicket:message 
key="instances.header.username">Username</wicket:message></th>
+                                                       <th class="header 
col-md-2"><wicket:message 
key="instances.header.status">Status</wicket:message></th>
+                                                       <th></th>
+                                               </tr>
+                                       </thead>
+                                       <tbody wicket:id="instancesTable">
+                                               <tr wicket:id="instances">
+                                                       <td>
+                                                               <a href="#" 
data-toggle="modal" data-target="#instanceInfo" wicket:id="editInstance">
+                                                                       <span 
wicket:id="name">Instance name</span>
+                                                               </a>
+                                                       </td>
+                                                       <td>
+                                                               <span 
wicket:id="host">Host</span>
+                                                       </td>
+                                                       <td>
+                                                               <span 
wicket:id="username">Username</span>
+                                                       </td>
+                                                       <td>
+                                                               <span 
wicket:id="connectionStatus" class="label">Status</span>
+                                                       </td>
+                                                       <td>
+                                                               <button 
class="btn btn-sm btn-danger" type="button" wicket:id="instanceDelete">
+                                                                       <span 
class="fa fa-trash-o"></span>
+                                                               </button>
+                                                       </td>
+                                               </tr>
+                                       </tbody>
+                               </table>
+                               <div wicket:id="instanceForm"></div>
+                               <button class="btn btn-sm btn-primary" 
wicket:id="addInstance">
+                                       <i class="fa fa-plus"></i> 
<wicket:message key="instances.buttons.addInstance">Add 
instance</wicket:message>
+                               </button>
+                       </div>
+                       <div class="col-lg-4">
+                               <div class="panel panel-primary">
+                                       <div class="panel-heading">
+                                               <h3 
class="panel-title">Help</h3>
+                                       </div>
+                                       <div class="panel-body">
+                                               <p>Some help about crawling</p>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+       </wicket:extend>
+</body>
+</html>
\ No newline at end of file

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.java 
(added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/instances/InstancesPage.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,111 @@
+package org.apache.nutch.webui.pages.instances;
+
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType.Danger;
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType.Info;
+import static 
de.agilecoders.wicket.core.markup.html.bootstrap.block.LabelType.Success;
+import static org.apache.nutch.webui.client.model.ConnectionStatus.CONNECTED;
+import static org.apache.nutch.webui.client.model.ConnectionStatus.CONNECTING;
+import static 
org.apache.nutch.webui.client.model.ConnectionStatus.DISCONNECTED;
+
+import java.util.Iterator;
+
+import org.apache.nutch.webui.client.model.ConnectionStatus;
+import org.apache.nutch.webui.model.NutchInstance;
+import org.apache.nutch.webui.pages.AbstractBasePage;
+import org.apache.nutch.webui.pages.components.ColorEnumLabel;
+import org.apache.nutch.webui.pages.components.ColorEnumLabelBuilder;
+import org.apache.nutch.webui.pages.components.CpmIteratorAdapter;
+import org.apache.nutch.webui.service.NutchInstanceService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.markup.repeater.RefreshingView;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.apache.wicket.util.time.Duration;
+
+public class InstancesPage extends AbstractBasePage<Void> {
+  @SpringBean
+  private NutchInstanceService instanceService;
+
+  private InstancePanel instancePanel;
+
+  private WebMarkupContainer instancesTable;
+  private static final Duration UPDATE_TIMEOUT = Duration.seconds(1);
+
+  public InstancesPage() {
+
+    instancesTable = new WebMarkupContainer("instancesTable");
+    instancesTable.setOutputMarkupId(true);
+    instancesTable.add(new AjaxSelfUpdatingTimerBehavior(UPDATE_TIMEOUT));
+
+    instancePanel = new InstancePanel("instanceForm");
+
+    RefreshingView<NutchInstance> instances = refreshingView();
+    instancesTable.add(instances);
+    add(instancesTable);
+    add(instancePanel);
+    add(addInstanceButton());
+  }
+
+  private RefreshingView<NutchInstance> refreshingView() {
+    RefreshingView<NutchInstance> instances = new 
RefreshingView<NutchInstance>(
+        "instances") {
+
+      @Override
+      protected Iterator<IModel<NutchInstance>> getItemModels() {
+        return new CpmIteratorAdapter<NutchInstance>(
+            instanceService.getInstances());
+      }
+
+      @Override
+      protected void populateItem(Item<NutchInstance> item) {
+        populateInstanceRow(item);
+      }
+    };
+    return instances;
+  }
+
+  private AjaxLink<NutchInstance> addInstanceButton() {
+    return new AjaxLink<NutchInstance>("addInstance") {
+      @Override
+      public void onClick(AjaxRequestTarget target) {
+        instancePanel.setModel(new CompoundPropertyModel<NutchInstance>(
+            new NutchInstance()));
+        target.add(instancePanel);
+        instancePanel.appendShowDialogJavaScript(target);
+      }
+    };
+  }
+
+  private void populateInstanceRow(final Item<NutchInstance> item) {
+    item.add(new AjaxLink<NutchInstance>("editInstance") {
+      @Override
+      public void onClick(AjaxRequestTarget target) {
+        instancePanel.setModel(item.getModel());
+        target.add(instancePanel);
+        instancePanel.appendShowDialogJavaScript(target);
+      }
+    }.add(new Label("name")));
+    item.add(new Label("host"));
+    item.add(new Label("username"));
+    item.add(createStatusLabel());
+    item.add(new AjaxLink<NutchInstance>("instanceDelete", item.getModel()) {
+      @Override
+      public void onClick(AjaxRequestTarget target) {
+        instanceService.removeInstance(getModelObject().getId());
+        target.add(instancesTable);
+      }
+    });
+  }
+
+  private ColorEnumLabel<ConnectionStatus> createStatusLabel() {
+    return new ColorEnumLabelBuilder<ConnectionStatus>("connectionStatus")
+        .withEnumColor(CONNECTED, Success).withEnumColor(CONNECTING, Info)
+        .withEnumColor(DISCONNECTED, Danger).build();
+  }
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.html?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.html 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.html 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,48 @@
+<!-- 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. -->
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+<title>Navbar</title>
+</head>
+<body>
+       <wicket:panel>
+               <div class="fluid-container" wicket:id="container">
+                       <!-- Brand and toggle get grouped for better mobile 
display -->
+                       <div class="navbar-header">
+                               <button type="button" class="navbar-toggle" 
data-toggle="collapse"
+                                       wicket:id="collapseButton">
+                                       <span class="sr-only" 
wicket:id="toggleNavigationLabel">[[CONTENT]]</span>
+                                       <span class="icon-bar"></span> <span 
class="icon-bar"></span> <span
+                                               class="icon-bar"></span>
+                               </button>
+                               <a wicket:id="brandName" class="navbar-brand" 
href="#"> <img
+                                       wicket:id="brandImage" /> <span 
wicket:id="brandLabel"></span>
+                               </a>
+                       </div>
+
+                       <div class="collapse navbar-collapse 
navbar-ex1-collapse"
+                               role="navigation" wicket:id="collapse">
+                               <ul class="nav navbar-nav side-nav">
+                                       <li wicket:id="navLeftList">
+                                               <div 
wicket:id="component">[[CONTENT]]</div>
+                                       </li>
+                               </ul>
+                               <ul wicket:enclosure="navRightList"
+                                       class="nav navbar-nav navbar-right">
+                                       <li wicket:id="navRightList">
+                                               <div 
wicket:id="component">[[CONTENT]]</div>
+                                       </li>
+                               </ul>
+                       </div>
+               </div>
+       </wicket:panel>
+</body>
+</html>

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/menu/VerticalMenu.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,28 @@
+/**
+ * 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 org.apache.nutch.webui.pages.menu;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.navbar.Navbar;
+
+public class VerticalMenu extends Navbar {
+
+  public VerticalMenu(String componentId) {
+    super(componentId);
+    // TODO Auto-generated constructor stub
+  }
+
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.html?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.html 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.html 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,75 @@
+<!-- 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. -->
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+<meta charset="utf-8" />
+<title>Wicket extend</title>
+</head>
+
+<body>
+       <wicket:extend>
+               <h2>
+                       <wicket:message key="navbar.menu.seedLists">Seed 
lists</wicket:message>
+               </h2>
+
+               <div class="row">
+                       <div class="col-lg-8">
+                               <div class="row">
+                                       <div class="col-lg-8 col-md-offset-10">
+                                               <button class="btn btn-success 
btn-default" wicket:id="newSeedList">
+                                                       <i class="fa 
fa-plus"></i> Add new list
+                                               </button>
+                                       </div>
+                               </div>
+                               <table class="table table-hover table-striped 
tablesorter">
+                                       <thead>
+                                               <tr>
+                                                       <th class="header 
col-md-3">Name</th>
+                                                       <th class="header 
col-md-2">Urls</th>
+                                                       <th></th>
+                                               </tr>
+                                       </thead>
+
+                                       <tbody>
+                                               <tr wicket:id="seedLists">
+                                                       <td>
+                                                               <a href="#" 
wicket:id="edit">
+                                                                       <span 
wicket:id="name">List name</span>
+                                                               </a>
+                                                       </td>
+                                                       <td>
+                                                               <span 
wicket:id="seedUrlsCount">10</span>
+                                                       </td>
+                                                       <td>
+                                                               <button 
class="btn btn-sm btn-danger" type="button" wicket:id="delete">
+                                                                       <span 
class="fa fa-trash-o"></span>
+                                                               </button>
+                                                       </td>
+                                               </tr>
+                                       </tbody>
+                               </table>
+                       </div>
+                       <div class="col-lg-4">
+                               <div class="panel panel-primary">
+                                       <div class="panel-heading">
+                                               <h3 
class="panel-title">Help</h3>
+                                       </div>
+                                       <div class="panel-body">
+                                               <p>Some help about seed 
lists</p>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+               <!--row-->
+       </wicket:extend>
+</body>
+</html>

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedListsPage.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,79 @@
+/**
+ * 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 org.apache.nutch.webui.pages.seed;
+
+import java.util.Iterator;
+
+import org.apache.nutch.webui.model.SeedList;
+import org.apache.nutch.webui.pages.AbstractBasePage;
+import org.apache.nutch.webui.pages.components.CpmIteratorAdapter;
+import org.apache.nutch.webui.service.SeedListService;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.markup.repeater.RefreshingView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+/**
+ * This page is for seed lists management
+ * 
+ * @author feodor
+ * 
+ */
+public class SeedListsPage extends AbstractBasePage<Void> {
+
+  @SpringBean
+  private SeedListService seedListService;
+
+  public SeedListsPage() {
+
+    RefreshingView<SeedList> seedLists = new RefreshingView<SeedList>(
+        "seedLists") {
+
+      @Override
+      protected Iterator<IModel<SeedList>> getItemModels() {
+        return new CpmIteratorAdapter<SeedList>(seedListService.findAll());
+      }
+
+      @Override
+      protected void populateItem(final Item<SeedList> item) {
+        PageParameters params = new PageParameters();
+        params.add("id", item.getModelObject().getId());
+
+        Link<Void> edit = new BookmarkablePageLink<Void>("edit",
+            SeedPage.class, params);
+        edit.add(new Label("name"));
+        item.add(edit);
+
+        item.add(new Label("seedUrlsCount"));
+
+        item.add(new Link<SeedList>("delete", item.getModel()) {
+          @Override
+          public void onClick() {
+            seedListService.delete(item.getModelObject().getId());
+          }
+        });
+      }
+    };
+
+    add(seedLists);
+    add(new BookmarkablePageLink<Void>("newSeedList", SeedPage.class));
+  }
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.html?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.html (added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.html Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,91 @@
+<!-- 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. -->
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+<meta charset="utf-8" />
+<title>Wicket extend</title>
+</head>
+
+<body>
+       <wicket:extend>
+               <h2>
+                       <wicket:message key="page.header.seedList">Seed 
list</wicket:message>
+               </h2>
+
+               <div class="row">
+                       <div class="col-lg-8">
+                               <form class="form-horizontal" 
wicket:id="seedList">
+                                       <fieldset>
+                                               <!-- Text input-->
+                                               <div class="form-group">
+                                                       <label class="col-md-4 
control-label" for="textinput">Seed list name</label>
+                                                       <div class="col-md-4">
+                                                               <input 
wicket:id="name" name="textinput" class="form-control input-md" type="text">
+                                                       </div>
+                                               </div>
+                                               <div class="form-group">
+                                                       <div 
class="col-md-offset-4 col-md-4">
+                                                               <button 
type="submit" class="btn btn-primary">Save</button>
+                                                       </div>
+                                               </div>
+                                       </fieldset>
+                               </form>
+                               <h3>Seed urls</h3>
+                               <table class="table table-hover table-striped 
tablesorter">
+                                       <thead>
+                                               <tr>
+                                                       <th class="header 
col-md-3">Url</th>
+                                                       <th></th>
+                                               </tr>
+                                       </thead>
+
+                                       <tbody wicket:id="seedUrlsTable">
+                                               <tr wicket:id="seedUrls">
+                                                       <td>
+                                                               <span 
wicket:id="url">http://google.com</span>
+                                                       </td>
+                                                       <td>
+                                                               <button 
wicket:id="delete" class="btn btn-sm btn-danger" type="button">
+                                                                       <span 
class="fa fa-trash-o"></span>
+                                                               </button>
+                                                       </td>
+                                               </tr>
+                                       </tbody>
+                               </table>
+                               <form class="form-horizontal" 
wicket:id="urlForm">
+                                       <fieldset>
+                                               <div class="form-group">
+                                                       <div class="col-md-4">
+                                                               <input 
wicket:id="url" name="textinput" class="form-control input-md" type="text">
+                                                       </div>
+                                                       <div>
+                                                               <button 
wicket:id="addUrl" class="btn btn-primary">Add url</button>
+                                                       </div>
+                                               </div>
+                                       </fieldset>
+                               </form>
+                       </div>
+                       <div class="col-lg-4">
+                               <div class="panel panel-primary">
+                                       <div class="panel-heading">
+                                               <h3 
class="panel-title">Help</h3>
+                                       </div>
+                                       <div class="panel-body">
+                                               <p>Some help about seed 
management</p>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+               <!--row-->
+       </wicket:extend>
+</body>
+</html>

Added: nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.java (added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/pages/seed/SeedPage.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,153 @@
+/**
+ * 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 org.apache.nutch.webui.pages.seed;
+
+import java.util.Iterator;
+
+import org.apache.nutch.webui.model.SeedList;
+import org.apache.nutch.webui.model.SeedUrl;
+import org.apache.nutch.webui.pages.AbstractBasePage;
+import org.apache.nutch.webui.pages.components.CpmIteratorAdapter;
+import org.apache.nutch.webui.service.SeedListService;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.markup.repeater.RefreshingView;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+import com.google.common.collect.Lists;
+
+/**
+ * This page is for seed urls management
+ * 
+ * @author feodor
+ * 
+ */
+public class SeedPage extends AbstractBasePage<SeedList> {
+
+  @SpringBean
+  private SeedListService seedListService;
+
+  private Form<SeedUrl> urlForm;
+
+  private WebMarkupContainer seedUrlsTable;
+
+  public SeedPage() {
+    SeedList list = new SeedList();
+    list.setSeedUrls(Lists.<SeedUrl> newArrayList());
+    initPage(Model.of(list));
+  }
+
+  public SeedPage(final PageParameters parameters) {
+    initPage(new LoadableDetachableModel<SeedList>() {
+
+      @Override
+      protected SeedList load() {
+        Long seedListId = parameters.get("id").toLongObject();
+        return seedListService.getSeedList(seedListId);
+      }
+    });
+  }
+
+  public void initPage(IModel<SeedList> model) {
+    setModel(new CompoundPropertyModel<SeedList>(model));
+
+    addBaseForm();
+    addSeedUrlsList();
+    addUrlForm();
+  }
+
+  private void addBaseForm() {
+    Form<SeedList> form = new Form<SeedList>("seedList", getModel()) {
+      @Override
+      protected void onSubmit() {
+        seedListService.save(getModelObject());
+        setResponsePage(SeedListsPage.class);
+      }
+    };
+    form.add(new TextField<String>("name"));
+    add(form);
+  }
+
+  private void addSeedUrlsList() {
+    seedUrlsTable = new WebMarkupContainer("seedUrlsTable");
+    seedUrlsTable.setOutputMarkupId(true);
+
+    RefreshingView<SeedUrl> seedUrls = new RefreshingView<SeedUrl>("seedUrls") 
{
+
+      @Override
+      protected Iterator<IModel<SeedUrl>> getItemModels() {
+        return new CpmIteratorAdapter<SeedUrl>(getModelObject().getSeedUrls());
+      }
+
+      @Override
+      protected void populateItem(Item<SeedUrl> item) {
+        item.add(new Label("url"));
+        item.add(new AjaxLink<SeedUrl>("delete", item.getModel()) {
+
+          @Override
+          public void onClick(AjaxRequestTarget target) {
+            deleteSeedUrl(getModelObject());
+            target.add(seedUrlsTable);
+          }
+        });
+      }
+    };
+    seedUrlsTable.add(seedUrls);
+    add(seedUrlsTable);
+  }
+
+  private void addUrlForm() {
+    urlForm = new Form<SeedUrl>("urlForm", CompoundPropertyModel.of(Model
+        .of(new SeedUrl())));
+    urlForm.setOutputMarkupId(true);
+    urlForm.add(new TextField<String>("url"));
+    urlForm.add(new AjaxSubmitLink("addUrl", urlForm) {
+      @Override
+      protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
+        addSeedUrl();
+        urlForm.setModelObject(new SeedUrl());
+        target.add(urlForm);
+        target.add(seedUrlsTable);
+      }
+    });
+    add(urlForm);
+  }
+
+  private void addSeedUrl() {
+    SeedUrl url = urlForm.getModelObject();
+    SeedList seedList = getModelObject();
+    url.setSeedList(seedList);
+    seedList.getSeedUrls().add(url);
+  }
+
+  private void deleteSeedUrl(SeedUrl url) {
+    SeedList seedList = getModelObject();
+    seedList.getSeedUrls().remove(url);
+  }
+
+}

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.html
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.html?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.html 
(added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.html 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+<meta charset="utf-8" />
+<title>Wicket extend</title>
+</head>
+
+<body>
+       <wicket:extend>
+               <h2>
+                       <wicket:message key="settings">Settings</wicket:message>
+               </h2>
+               <div class="row">
+                       <div class="col-lg-12">
+                               <table class="table table-hover tablesorter 
table-bordered">
+                                       <thead>
+                                               <tr>
+                                                       <th class="header 
col-lg-3">
+                                                               <wicket:message 
key="settings.header.name">Name</wicket:message>
+                                                       </th>
+                                                       <th class="header 
col-lg-9">
+                                                               <wicket:message 
key="settings.header.value">Value</wicket:message>
+                                                       </th>
+                                               </tr>
+                                       </thead>
+                                       <tbody wicket:id="settingsTable">
+                                               <tr wicket:id="settings">
+                                                       <td>
+                                                               <span 
wicket:id="name">Name</span>
+                                                       </td>
+                                                       <td>
+<!--                                                           <span 
wicket:id="value">Value</span> -->
+                                       <input class="col-lg-12" 
wicket:id="value" placeholder="http://localhost:8080";>
+                                                       </td>
+                                               </tr>
+                                       </tbody>
+                               </table>
+                       </div>
+               </div>
+       </wicket:extend>
+
+</body>
+</html>

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.java 
(added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/pages/settings/SettingsPage.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,59 @@
+package org.apache.nutch.webui.pages.settings;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.nutch.webui.model.NutchConfig;
+import org.apache.nutch.webui.pages.AbstractBasePage;
+import org.apache.nutch.webui.pages.components.CpmIteratorAdapter;
+import org.apache.nutch.webui.service.NutchService;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.markup.repeater.RefreshingView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+public class SettingsPage extends AbstractBasePage<Void> {
+  @SpringBean
+  private NutchService nutchService;
+
+  private WebMarkupContainer settingsTable;
+
+  public SettingsPage() {
+    settingsTable = new WebMarkupContainer("settingsTable");
+    settingsTable.setOutputMarkupId(true);
+    RefreshingView<NutchConfig> nutchConfig = new RefreshingView<NutchConfig>(
+        "settings") {
+
+      @Override
+      protected Iterator<IModel<NutchConfig>> getItemModels() {
+        return new CpmIteratorAdapter<NutchConfig>(
+            convertNutchConfig(nutchService.getNutchConfig(getCurrentInstance()
+                .getId())));
+      }
+
+      @Override
+      protected void populateItem(Item<NutchConfig> item) {
+        item.add(new Label("name"));
+        item.add(new TextField<String>("value"));
+      }
+    };
+    settingsTable.add(nutchConfig);
+    add(settingsTable);
+  }
+
+  private List<NutchConfig> convertNutchConfig(Map<String, String> map) {
+    List<NutchConfig> listNutchConfigs = new LinkedList<NutchConfig>();
+    for (String key : map.keySet()) {
+      NutchConfig conf = new NutchConfig();
+      conf.setName(key);
+      conf.setValue(map.get(key));
+      listNutchConfigs.add(conf);
+    }
+    return listNutchConfigs;
+  }
+}

Added: nutch/trunk/src/java/org/apache/nutch/webui/service/CrawlService.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/service/CrawlService.java?rev=1705744&view=auto
==============================================================================
--- nutch/trunk/src/java/org/apache/nutch/webui/service/CrawlService.java 
(added)
+++ nutch/trunk/src/java/org/apache/nutch/webui/service/CrawlService.java Mon 
Sep 28 18:58:33 2015
@@ -0,0 +1,33 @@
+/**
+ * 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 org.apache.nutch.webui.service;
+
+import java.util.List;
+
+import org.apache.nutch.webui.client.model.Crawl;
+import org.apache.nutch.webui.model.NutchInstance;
+
+public interface CrawlService {
+
+  public void saveCrawl(Crawl crawl);
+
+  public List<Crawl> getCrawls();
+
+  void startCrawl(Long crawlId, NutchInstance instance);
+
+  void deleteCrawl(Long crawlId);
+}

Added: 
nutch/trunk/src/java/org/apache/nutch/webui/service/NutchInstanceService.java
URL: 
http://svn.apache.org/viewvc/nutch/trunk/src/java/org/apache/nutch/webui/service/NutchInstanceService.java?rev=1705744&view=auto
==============================================================================
--- 
nutch/trunk/src/java/org/apache/nutch/webui/service/NutchInstanceService.java 
(added)
+++ 
nutch/trunk/src/java/org/apache/nutch/webui/service/NutchInstanceService.java 
Mon Sep 28 18:58:33 2015
@@ -0,0 +1,33 @@
+/**
+ * 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 org.apache.nutch.webui.service;
+
+import java.util.List;
+
+import org.apache.nutch.webui.model.NutchInstance;
+
+public interface NutchInstanceService {
+
+  public List<NutchInstance> getInstances();
+
+  public void saveInstance(NutchInstance instance);
+
+  public void removeInstance(Long id);
+
+  public NutchInstance getInstance(Long id);
+
+}



Reply via email to