Repository: syncope
Updated Branches:
  refs/heads/master 3f0f25623 -> 3147ee761


[SYNCOPE-744][SYNCOPE-750] Configuration completeness widget


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/3147ee76
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/3147ee76
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/3147ee76

Branch: refs/heads/master
Commit: 3147ee7610630d22754eda79f575519a9f05c935
Parents: 3f0f256
Author: Francesco Chicchiriccò <[email protected]>
Authored: Wed Feb 17 17:55:12 2016 +0100
Committer: Francesco Chicchiriccò <[email protected]>
Committed: Wed Feb 17 17:55:12 2016 +0100

----------------------------------------------------------------------
 .../client/console/annotations/ExtPage.java     |   5 +
 .../syncope/client/console/pages/BasePage.java  |  72 ++++++-----
 .../syncope/client/console/pages/Dashboard.java |   2 +
 .../console/widgets/CompletenessWidget.java     | 123 +++++++++++++++++++
 .../syncope/client/console/pages/Dashboard.html |  15 ++-
 .../console/widgets/AnyByRealmWidget.html       |  18 ++-
 .../console/widgets/CompletenessWidget.html     |  46 +++++++
 .../widgets/CompletenessWidget.properties       |  25 ++++
 .../widgets/CompletenessWidget_it.properties    |  25 ++++
 .../widgets/CompletenessWidget_pt_BR.properties |  25 ++++
 .../client/console/widgets/LoadWidget.html      |  36 +++---
 .../console/widgets/UsersByStatusWidget.html    |  18 ++-
 .../syncope/common/lib/info/NumbersInfo.java    |  36 ++++++
 .../apache/syncope/core/logic/SyncopeLogic.java |  41 +++++++
 .../client/console/pages/CamelRoutes.java       |   2 +-
 15 files changed, 412 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/java/org/apache/syncope/client/console/annotations/ExtPage.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/annotations/ExtPage.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/annotations/ExtPage.java
index 18ce9f5..f0ed504 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/annotations/ExtPage.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/annotations/ExtPage.java
@@ -41,6 +41,11 @@ public @interface ExtPage {
     String icon() default "fa-circle-o";
 
     /**
+     * @return the entitlement required to access this extension page
+     */
+    String listEntitlement();
+
+    /**
      * @return the priority used to determine the display order under the 
"Extensions" menu item, on the left pane; the
      * higher value, the higher rank
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index bbf4985..79d6e5a 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -109,7 +109,7 @@ public class BasePage extends WebPage implements 
NotificationAwareComponent, IAj
             todos.setDefaultModelObject(new 
UserWorkflowRestClient().getForms().size());
         }
         MetaDataRoleAuthorizationStrategy.authorize(
-                todosContainer, WebPage.RENDER, 
StandardEntitlement.WORKFLOW_FORM_LIST);
+                todosContainer, WebPage.ENABLE, 
StandardEntitlement.WORKFLOW_FORM_LIST);
 
         // menu
         WebMarkupContainer liContainer = new 
WebMarkupContainer(getLIContainerId("dashboard"));
@@ -118,19 +118,22 @@ public class BasePage extends WebPage implements 
NotificationAwareComponent, IAj
 
         liContainer = new WebMarkupContainer(getLIContainerId("realms"));
         body.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("realms", 
Realms.class));
-        MetaDataRoleAuthorizationStrategy.authorize(liContainer, 
WebPage.RENDER, StandardEntitlement.REALM_LIST);
+        BookmarkablePageLink<Page> link = 
BookmarkablePageLinkBuilder.build("realms", Realms.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.REALM_LIST);
+        liContainer.add(link);
 
         liContainer = new WebMarkupContainer(getLIContainerId("topology"));
         body.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("topology", 
Topology.class));
-        MetaDataRoleAuthorizationStrategy.authorize(liContainer, 
WebPage.RENDER,
+        link = BookmarkablePageLinkBuilder.build("topology", Topology.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE,
                 String.format("%s,%s", StandardEntitlement.CONNECTOR_LIST, 
StandardEntitlement.RESOURCE_LIST));
+        liContainer.add(link);
 
         liContainer = new WebMarkupContainer(getLIContainerId("reports"));
         body.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("reports", 
Reports.class));
-        MetaDataRoleAuthorizationStrategy.authorize(liContainer, 
WebPage.RENDER, StandardEntitlement.REPORT_LIST);
+        link = BookmarkablePageLinkBuilder.build("reports", Reports.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.REPORT_LIST);
+        liContainer.add(link);
 
         WebMarkupContainer confLIContainer = new 
WebMarkupContainer(getLIContainerId("configuration"));
         body.add(confLIContainer);
@@ -139,54 +142,55 @@ public class BasePage extends WebPage implements 
NotificationAwareComponent, IAj
 
         liContainer = new WebMarkupContainer(getLIContainerId("workflow"));
         confULContainer.add(liContainer);
-        BookmarkablePageLink<Page> workflowLink = 
BookmarkablePageLinkBuilder.build("workflow", Workflow.class);
-        MetaDataRoleAuthorizationStrategy.authorize(
-                workflowLink, WebPage.ENABLE, 
StandardEntitlement.WORKFLOW_DEF_READ);
-        liContainer.add(workflowLink);
+        link = BookmarkablePageLinkBuilder.build("workflow", Workflow.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.WORKFLOW_DEF_READ);
+        liContainer.add(link);
 
         liContainer = new WebMarkupContainer(getLIContainerId("logs"));
         confULContainer.add(liContainer);
-        BookmarkablePageLink<Page> logsLink = 
BookmarkablePageLinkBuilder.build("logs", Logs.class);
-        MetaDataRoleAuthorizationStrategy.authorize(logsLink, WebPage.ENABLE, 
StandardEntitlement.LOG_LIST);
-        liContainer.add(logsLink);
-        MetaDataRoleAuthorizationStrategy.authorize(liContainer, 
WebPage.RENDER, StandardEntitlement.LOG_LIST);
+        link = BookmarkablePageLinkBuilder.build("logs", Logs.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.LOG_LIST);
+        liContainer.add(link);
 
         liContainer = new 
WebMarkupContainer(getLIContainerId("securityquestions"));
         confULContainer.add(liContainer);
-        BookmarkablePageLink<Page> secuityQuestionsLink =
-                BookmarkablePageLinkBuilder.build("securityquestions", 
SecurityQuestions.class);
-        liContainer.add(secuityQuestionsLink);
+        liContainer.add(BookmarkablePageLinkBuilder.build("securityquestions", 
SecurityQuestions.class));
 
         liContainer = new WebMarkupContainer(getLIContainerId("types"));
         confULContainer.add(liContainer);
-        BookmarkablePageLink<Page> typesLink = 
BookmarkablePageLinkBuilder.build("types", Types.class);
-        MetaDataRoleAuthorizationStrategy.authorize(typesLink, WebPage.ENABLE, 
StandardEntitlement.SCHEMA_LIST);
-        liContainer.add(typesLink);
+        link = BookmarkablePageLinkBuilder.build("types", Types.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.SCHEMA_LIST);
+        liContainer.add(link);
 
         liContainer = new WebMarkupContainer(getLIContainerId("roles"));
         confULContainer.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("roles", 
Roles.class));
-        MetaDataRoleAuthorizationStrategy.authorize(liContainer, 
WebPage.RENDER, StandardEntitlement.ROLE_LIST);
+        link = BookmarkablePageLinkBuilder.build("roles", Roles.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.ROLE_LIST);
+        liContainer.add(link);
 
         liContainer = new WebMarkupContainer(getLIContainerId("policies"));
         confULContainer.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("policies", 
Policies.class));
-        MetaDataRoleAuthorizationStrategy.authorize(liContainer, 
WebPage.RENDER, StandardEntitlement.POLICY_LIST);
+        link = BookmarkablePageLinkBuilder.build("policies", Policies.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.POLICY_LIST);
+        liContainer.add(link);
 
         liContainer = new WebMarkupContainer(getLIContainerId("layouts"));
         confULContainer.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("layouts", 
Layouts.class));
+        link = BookmarkablePageLinkBuilder.build("layouts", Layouts.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.CONFIGURATION_LIST);
+        liContainer.add(link);
 
         liContainer = new 
WebMarkupContainer(getLIContainerId("notifications"));
         confULContainer.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("notifications", 
Notifications.class));
-        MetaDataRoleAuthorizationStrategy.authorize(liContainer, 
WebPage.RENDER, StandardEntitlement.NOTIFICATION_LIST);
+        link = BookmarkablePageLinkBuilder.build("notifications", 
Notifications.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.NOTIFICATION_LIST);
+        liContainer.add(link);
 
         liContainer = new WebMarkupContainer(getLIContainerId("parameters"));
         confULContainer.add(liContainer);
-        liContainer.add(BookmarkablePageLinkBuilder.build("parameters", 
Parameters.class));
-        MetaDataRoleAuthorizationStrategy.authorize(
-                liContainer, WebPage.RENDER, 
StandardEntitlement.CONFIGURATION_LIST);
+        link = BookmarkablePageLinkBuilder.build("parameters", 
Parameters.class);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.CONFIGURATION_LIST);
+        liContainer.add(link);
 
         body.add(new AjaxLink<Void>("collapse") {
 
@@ -279,12 +283,12 @@ public class BasePage extends WebPage implements 
NotificationAwareComponent, IAj
                     });
                 }
 
-                BookmarkablePageLink<Page> link = new 
BookmarkablePageLink<>("extPage", item.getModelObject());
-                containingLI.add(link);
-
                 ExtPage ann = 
item.getModelObject().getAnnotation(ExtPage.class);
 
+                BookmarkablePageLink<Page> link = new 
BookmarkablePageLink<>("extPage", item.getModelObject());
                 link.add(new Label("extPageLabel", ann.label()));
+                MetaDataRoleAuthorizationStrategy.authorize(link, 
WebPage.ENABLE, ann.listEntitlement());
+                containingLI.add(link);
 
                 Label extPageIcon = new Label("extPageIcon");
                 extPageIcon.add(new AttributeModifier("class", "fa " + 
ann.icon()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
index 6300d0a..396ec2f 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/pages/Dashboard.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.pages;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.widgets.NumberWidget;
 import org.apache.syncope.client.console.widgets.AnyByRealmWidget;
+import org.apache.syncope.client.console.widgets.CompletenessWidget;
 import org.apache.syncope.client.console.widgets.LoadWidget;
 import org.apache.syncope.client.console.widgets.UsersByStatusWidget;
 import org.apache.syncope.common.lib.info.NumbersInfo;
@@ -67,6 +68,7 @@ public class Dashboard extends BasePage {
         body.add(new NumberWidget("totalAny1OrResources", "bg-aqua", number, 
label, icon));
 
         body.add(new UsersByStatusWidget("usersByStatus", 
numbers.getUsersByStatus()));
+        body.add(new CompletenessWidget("completeness", 
numbers.getConfCompleteness()));
         body.add(new AnyByRealmWidget(
                 "anyByRealm",
                 numbers.getUsersByRealm(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
new file mode 100644
index 0000000..972768f
--- /dev/null
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
@@ -0,0 +1,123 @@
+/*
+ * 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.syncope.client.console.widgets;
+
+import com.pingunaut.wicket.chartjs.chart.impl.Doughnut;
+import com.pingunaut.wicket.chartjs.core.panel.DoughnutChartPanel;
+import java.util.Map;
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
+import org.apache.syncope.client.console.pages.Notifications;
+import org.apache.syncope.client.console.pages.Policies;
+import org.apache.syncope.client.console.pages.Roles;
+import org.apache.syncope.client.console.pages.SecurityQuestions;
+import org.apache.syncope.client.console.pages.Types;
+import org.apache.syncope.client.console.topology.Topology;
+import org.apache.syncope.common.lib.info.NumbersInfo;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.Page;
+import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.model.Model;
+
+public class CompletenessWidget extends AbstractWidget {
+
+    private static final long serialVersionUID = 7667120094526529934L;
+
+    public CompletenessWidget(final String id, final Map<NumbersInfo.ConfItem, 
Boolean> confCompleteness) {
+        super(id);
+
+        Doughnut doughnut = new Doughnut();
+        doughnut.getOptions().setResponsive(true);
+        doughnut.getOptions().setMaintainAspectRatio(true);
+        doughnut.getOptions().setTooltipTemplate("<%= label %>");
+
+        int done = 0;
+        int todo = 0;
+        for (Map.Entry<NumbersInfo.ConfItem, Boolean> entry : 
confCompleteness.entrySet()) {
+            if (entry.getValue()) {
+                done += entry.getKey().getScore();
+            } else {
+                todo++;
+            }
+        }
+
+        doughnut.getData().add(
+                new LabeledDoughnutChartData(done, "blue", getString("done")));
+        doughnut.getData().add(
+                new LabeledDoughnutChartData(100 - done, "red", 
getString("todo") + ": " + todo));
+
+        add(new DoughnutChartPanel("chart", Model.of(doughnut)));
+
+        BookmarkablePageLink<Page> link = 
BookmarkablePageLinkBuilder.build("topology", Topology.class);
+        link.setOutputMarkupPlaceholderTag(true);
+        add(link);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE,
+                String.format("%s,%s", StandardEntitlement.CONNECTOR_LIST, 
StandardEntitlement.RESOURCE_LIST));
+        if (confCompleteness.get(NumbersInfo.ConfItem.RESOURCE)
+                || confCompleteness.get(NumbersInfo.ConfItem.SYNC_TASK)) {
+
+            link.setVisible(false);
+        }
+
+        link = BookmarkablePageLinkBuilder.build("policies", Policies.class);
+        link.setOutputMarkupPlaceholderTag(true);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.POLICY_LIST);
+        add(link);
+        if (confCompleteness.get(NumbersInfo.ConfItem.ACCOUNT_POLICY)
+                || confCompleteness.get(NumbersInfo.ConfItem.PASSWORD_POLICY)) 
{
+
+            link.setVisible(false);
+        }
+
+        link = BookmarkablePageLinkBuilder.build("notifications", 
Notifications.class);
+        link.setOutputMarkupPlaceholderTag(true);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.NOTIFICATION_LIST);
+        add(link);
+        if (confCompleteness.get(NumbersInfo.ConfItem.NOTIFICATION)) {
+            link.setVisible(false);
+        }
+
+        link = BookmarkablePageLinkBuilder.build("types", Types.class);
+        link.setOutputMarkupPlaceholderTag(true);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.SCHEMA_LIST);
+        add(link);
+        if (confCompleteness.get(NumbersInfo.ConfItem.VIR_SCHEMA)
+                || confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE)) {
+
+            link.setVisible(false);
+        }
+
+        link = BookmarkablePageLinkBuilder.build("securityquestions", 
SecurityQuestions.class);
+        link.setOutputMarkupPlaceholderTag(true);
+        add(link);
+        if (confCompleteness.get(NumbersInfo.ConfItem.SECURITY_QUESTION)) {
+            link.setVisible(false);
+        }
+
+        link = BookmarkablePageLinkBuilder.build("roles", Roles.class);
+        link.setOutputMarkupPlaceholderTag(true);
+        MetaDataRoleAuthorizationStrategy.authorize(link, WebPage.ENABLE, 
StandardEntitlement.ROLE_LIST);
+        add(link);
+        if (confCompleteness.get(NumbersInfo.ConfItem.ROLE)) {
+            link.setVisible(false);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
index 9a694cb..c6eb390 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Dashboard.html
@@ -34,12 +34,21 @@ under the License.
       </div>
 
       <div class="row">
-        <span wicket:id="usersByStatus"/>
-        <span wicket:id="anyByRealm"/>
+        <div class="col-md-4">
+          <span wicket:id="usersByStatus"/>
+        </div>
+        <div class="col-md-4">
+          <span wicket:id="completeness"/>
+        </div>
+        <div class="col-md-4">
+          <span wicket:id="load"/>
+        </div>
       </div>
 
       <div class="row">
-        <span wicket:id="load"/>
+        <div class="col-md-6">
+          <span wicket:id="anyByRealm"/>
+        </div>
       </div>
     </section>
   </wicket:extend>

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
index 7a8e1f5..c2f9ce3 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/AnyByRealmWidget.html
@@ -18,18 +18,16 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
   <wicket:panel>
-    <div class="col-md-6">
-      <div class="box">
-        <div class="box-header with-border">
-          <h3 class="box-title"><wicket:message 
key="usersGroupsAndAnyObjectsDistribution"/></h3>
-          <div class="box-tools pull-right">
-            <button class="btn btn-box-tool" data-widget="collapse"><i 
class="fa fa-minus"></i></button>
-          </div>
-        </div>
-        <div class="box-body">
-          <div class="chart" wicket:id="chart"/>
+    <div class="box">
+      <div class="box-header with-border">
+        <h3 class="box-title"><wicket:message 
key="usersGroupsAndAnyObjectsDistribution"/></h3>
+        <div class="box-tools pull-right">
+          <button class="btn btn-box-tool" data-widget="collapse"><i class="fa 
fa-minus"></i></button>
         </div>
       </div>
+      <div class="box-body">
+        <div class="chart" wicket:id="chart"/>
+      </div>
     </div>
   </wicket:panel>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
new file mode 100644
index 0000000..c57d40b
--- /dev/null
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.html
@@ -0,0 +1,46 @@
+<!--
+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="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+  <wicket:panel>
+    <div class="box">
+      <div class="box-header with-border">
+        <h3 class="box-title"><wicket:message key="configurationStatus"/></h3>
+        <div class="box-tools pull-right">
+          <div class="btn-group">
+            <button class="btn btn-box-tool dropdown-toggle" 
data-toggle="dropdown">
+              <i class="fa fa-wrench"></i>
+            </button>
+            <ul class="dropdown-menu" role="menu">
+              <li><a href="#" wicket:id="topology"><wicket:message 
key="createResourceOrSyncTask"/></a></li>
+              <li><a href="#" wicket:id="policies"><wicket:message 
key="createPolicy"/></a></li>
+              <li><a href="#" wicket:id="notifications"><wicket:message 
key="createNotification"/></a></li>
+              <li><a href="#" wicket:id="types"><wicket:message 
key="createVirSchemaOrAnyType"/></a></li>
+              <li><a href="#" wicket:id="securityquestions"><wicket:message 
key="createSecurityQuestion"/></a></li>
+              <li><a href="#" wicket:id="roles"><wicket:message 
key="createRole"/></a></li>
+            </ul>
+          </div>
+          <button class="btn btn-box-tool" data-widget="collapse"><i class="fa 
fa-minus"></i></button>
+        </div>
+      </div>
+      <div class="box-body">
+        <div class="chart" wicket:id="chart"/>
+      </div>
+    </div>
+  </wicket:panel>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
new file mode 100644
index 0000000..e40cc59
--- /dev/null
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget.properties
@@ -0,0 +1,25 @@
+# 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.
+configurationStatus=Configuration Status
+createResourceOrSyncTask=Create Resource or SyncTask
+createPolicy=Create Policy
+createVirSchemaOrAnyType=Create Virtual Schema or AnyType
+createSecurityQuestion=Create Security Question
+createRole=Create Role
+createNotification=Create Notification
+done=Done
+todo=To do

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
new file mode 100644
index 0000000..641d93e
--- /dev/null
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_it.properties
@@ -0,0 +1,25 @@
+# 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.
+configurationStatus=Stato Configurazione
+createResourceOrSyncTask=Crea Risorsa o SyncTask
+createPolicy=Crea Politica
+createVirSchemaOrAnyType=Crea Virtual Schema o AnyType
+createSecurityQuestion=Crea Domanda di Sicurezza
+createRole=Crea Ruolo
+createNotification=Crea Notifica
+done=Fatto
+todo=Da fare

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
new file mode 100644
index 0000000..d921be0
--- /dev/null
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/CompletenessWidget_pt_BR.properties
@@ -0,0 +1,25 @@
+# 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.
+configurationStatus=Estado de configura\u00e7\u00e3o
+createResourceOrSyncTask=Criar recursos ou SyncTask
+createPolicy=Criar Politica
+createVirSchemaOrAnyType=Criar Virtual Schema ou AnyType
+createSecurityQuestion=Criar Perguntas de Seguran\u00e7a 
+createRole=Criar Fun\u00e7\u00e3o
+createNotification=Criar Notifica\u00e7\u00e3o
+done=Feito
+todo=Fazer

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
index 82aff57..d6a4260 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/LoadWidget.html
@@ -18,27 +18,25 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
   <wicket:panel>
-    <div class="col-md-6">
-      <div class="box">
-        <div class="box-header with-border">
-          <h3 class="box-title"><wicket:message key="systemLoad"/></h3>
-          <div class="box-tools pull-right">
-            <div class="btn-group">
-              <button class="btn btn-box-tool dropdown-toggle" 
data-toggle="dropdown">
-                <i class="fa fa-info"></i>
-              </button>
-              <ul class="dropdown-menu" role="menu">
-                <li><a href="#"><span wicket:id="hostname"/></a></li>
-                <li><a href="#"><span wicket:id="os"/></a></li>
-                <li><a href="#"><span wicket:id="jvm"/></a></li>
-              </ul>
-            </div>
-            <button class="btn btn-box-tool" data-widget="collapse"><i 
class="fa fa-minus"></i></button>
+    <div class="box">
+      <div class="box-header with-border">
+        <h3 class="box-title"><wicket:message key="systemLoad"/></h3>
+        <div class="box-tools pull-right">
+          <div class="btn-group">
+            <button class="btn btn-box-tool dropdown-toggle" 
data-toggle="dropdown">
+              <i class="fa fa-info"></i>
+            </button>
+            <ul class="dropdown-menu" role="menu">
+              <li><a href="#"><span wicket:id="hostname"/></a></li>
+              <li><a href="#"><span wicket:id="os"/></a></li>
+              <li><a href="#"><span wicket:id="jvm"/></a></li>
+            </ul>
           </div>
+          <button class="btn btn-box-tool" data-widget="collapse"><i class="fa 
fa-minus"></i></button>
         </div>
-        <div class="box-body">
-          <div class="chart" wicket:id="chart"/>
-        </div>
+      </div>
+      <div class="box-body">
+        <div class="chart" wicket:id="chart"/>
       </div>
     </div>
   </wicket:panel>

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
index 0cdfd1f..ce24a16 100644
--- 
a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
+++ 
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/UsersByStatusWidget.html
@@ -18,18 +18,16 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
   <wicket:panel>
-    <div class="col-md-6">
-      <div class="box">
-        <div class="box-header with-border">
-          <h3 class="box-title"><wicket:message key="userStatus"/></h3>
-          <div class="box-tools pull-right">
-            <button class="btn btn-box-tool" data-widget="collapse"><i 
class="fa fa-minus"></i></button>
-          </div>
-        </div>
-        <div class="box-body">
-          <div class="chart" wicket:id="chart"/>
+    <div class="box">
+      <div class="box-header with-border">
+        <h3 class="box-title"><wicket:message key="userStatus"/></h3>
+        <div class="box-tools pull-right">
+          <button class="btn btn-box-tool" data-widget="collapse"><i class="fa 
fa-minus"></i></button>
         </div>
       </div>
+      <div class="box-body">
+        <div class="chart" wicket:id="chart"/>
+      </div>
     </div>
   </wicket:panel>
 </html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/common/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java 
b/common/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
index a831e76..293bb55 100644
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
+++ 
b/common/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.HashMap;
 import java.util.Map;
+import javax.xml.bind.annotation.XmlEnum;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -34,6 +35,32 @@ public class NumbersInfo extends AbstractBaseBean {
 
     private static final long serialVersionUID = 7691187370598649583L;
 
+    @XmlEnum
+    @XmlType(name = "confItem")
+    public enum ConfItem {
+
+        RESOURCE(20),
+        ACCOUNT_POLICY(10),
+        PASSWORD_POLICY(10),
+        NOTIFICATION(8),
+        SYNC_TASK(10),
+        VIR_SCHEMA(10),
+        ANY_TYPE(5),
+        SECURITY_QUESTION(12),
+        ROLE(15);
+
+        private final int score;
+
+        ConfItem(final int score) {
+            this.score = score;
+        }
+
+        public int getScore() {
+            return score;
+        }
+
+    }
+
     private int totalUsers;
 
     @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
@@ -70,6 +97,10 @@ public class NumbersInfo extends AbstractBaseBean {
 
     private int totalRoles;
 
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
+    private final Map<ConfItem, Boolean> confCompleteness = new HashMap<>();
+
     public int getTotalUsers() {
         return totalUsers;
     }
@@ -159,4 +190,9 @@ public class NumbersInfo extends AbstractBaseBean {
         return any2ByRealm;
     }
 
+    @JsonProperty
+    public Map<ConfItem, Boolean> getConfCompleteness() {
+        return confCompleteness;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java 
b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index f15167d..f72d6e9 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -33,6 +33,8 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 import org.apache.syncope.common.lib.info.NumbersInfo;
 import org.apache.syncope.common.lib.info.SystemInfo;
 import org.apache.syncope.common.lib.info.PlatformInfo;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.core.misc.security.PasswordGenerator;
 import org.apache.syncope.core.persistence.api.ImplementationLookup;
 import org.apache.syncope.core.persistence.api.ImplementationLookup.Type;
@@ -40,8 +42,13 @@ import 
org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.ConfDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
@@ -80,9 +87,24 @@ public class SyncopeLogic extends 
AbstractLogic<AbstractBaseBean> {
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
+    private PolicyDAO policyDAO;
+
+    @Autowired
+    private NotificationDAO notificationDAO;
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
     private RoleDAO roleDAO;
 
     @Autowired
+    private SecurityQuestionDAO securityQuestionDAO;
+
+    @Autowired
     private ConfDAO confDAO;
 
     @Resource(name = "version")
@@ -254,6 +276,25 @@ public class SyncopeLogic extends 
AbstractLogic<AbstractBaseBean> {
 
         numbersInfo.setTotalRoles(roleDAO.count());
 
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.RESOURCE, numbersInfo.getTotalResources() 
> 0);
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.ACCOUNT_POLICY, 
!policyDAO.find(PolicyType.ACCOUNT).isEmpty());
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.PASSWORD_POLICY, 
!policyDAO.find(PolicyType.PASSWORD).isEmpty());
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.NOTIFICATION, 
!notificationDAO.findAll().isEmpty());
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.SYNC_TASK, 
!taskDAO.findAll(TaskType.SYNCHRONIZATION).isEmpty());
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.VIR_SCHEMA, 
!virSchemaDAO.findAll().isEmpty());
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.ANY_TYPE, !anyObjectNumbers.isEmpty());
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.SECURITY_QUESTION, 
!securityQuestionDAO.findAll().isEmpty());
+        numbersInfo.getConfCompleteness().put(
+                NumbersInfo.ConfItem.ROLE, numbersInfo.getTotalRoles() > 0);
+
         return numbersInfo;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/3147ee76/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
----------------------------------------------------------------------
diff --git 
a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
 
b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
index e8f5e26..b53d162 100644
--- 
a/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
+++ 
b/ext/camel/client-console/src/main/java/org/apache/syncope/client/console/pages/CamelRoutes.java
@@ -34,7 +34,7 @@ import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
-@ExtPage(label = "Camel Routes", icon = "fa-road", priority = 100)
+@ExtPage(label = "Camel Routes", icon = "fa-road", listEntitlement = 
CamelEntitlement.ROUTE_LIST, priority = 100)
 public class CamelRoutes extends AbstractExtPage {
 
     private static final long serialVersionUID = 1965360932245590233L;

Reply via email to