You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2016/03/07 16:52:19 UTC
[3/6] syncope git commit: [SYNCOPE-744] Here is the reconciliation
status widget
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java
new file mode 100644
index 0000000..0e5addc
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.java
@@ -0,0 +1,177 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.SearchableDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.AbstractModalPanel;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.widgets.reconciliation.Any;
+import org.apache.syncope.client.console.widgets.reconciliation.Misaligned;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class ReconciliationDetailsModalPanel extends AbstractModalPanel<Any> {
+
+ private static final long serialVersionUID = 1469396040405535283L;
+
+ private static final int ROWS = 10;
+
+ private final String resource;
+
+ private final List<Misaligned> misaligned;
+
+ public ReconciliationDetailsModalPanel(
+ final BaseModal<Any> modal,
+ final String resource,
+ final List<Misaligned> misaligned,
+ final PageReference pageRef) {
+
+ super(modal, pageRef);
+ this.resource = resource;
+ this.misaligned = misaligned;
+
+ add(new DiffPanel("diff", pageRef));
+ }
+
+ private class DiffPanel extends AbstractSearchResultPanel<
+ Misaligned, Misaligned, DetailsProvider, BaseRestClient> {
+
+ private static final long serialVersionUID = -8214546246301342868L;
+
+ DiffPanel(final String id, final PageReference pageRef) {
+ super(id, new Builder<Misaligned, Misaligned, BaseRestClient>(null, pageRef) {
+
+ private static final long serialVersionUID = 8769126634538601689L;
+
+ @Override
+ protected WizardMgtPanel<Misaligned> newInstance(final String id) {
+ return new DiffPanel(id, pageRef);
+ }
+ }.disableCheckBoxes().hidePaginator());
+
+ rows = 10;
+ initResultTable();
+ }
+
+ @Override
+ protected DetailsProvider dataProvider() {
+ return new DetailsProvider();
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBulkActions() {
+ return Collections.<ActionLink.ActionType>emptyList();
+ }
+
+ @Override
+ protected List<IColumn<Misaligned, String>> getColumns() {
+ List<IColumn<Misaligned, String>> columns = new ArrayList<>();
+
+ columns.add(new PropertyColumn<Misaligned, String>(new ResourceModel("key"), "name", "name"));
+
+ columns.add(new AbstractColumn<Misaligned, String>(Model.of("Syncope")) {
+
+ private static final long serialVersionUID = 2054811145491901166L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<Misaligned>> cellItem,
+ final String componentId,
+ final IModel<Misaligned> rowModel) {
+
+ cellItem.add(new Label(componentId, rowModel.getObject().getOnSyncope().toString()));
+ cellItem.add(new AttributeModifier("class", "code-deletion"));
+ }
+ });
+
+ columns.add(new AbstractColumn<Misaligned, String>(Model.of(resource)) {
+
+ private static final long serialVersionUID = 2054811145491901166L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<Misaligned>> cellItem,
+ final String componentId,
+ final IModel<Misaligned> rowModel) {
+
+ cellItem.add(new Label(componentId, rowModel.getObject().getOnResource().toString()));
+ cellItem.add(new AttributeModifier("class", "code-addition"));
+ }
+ });
+
+ return columns;
+ }
+ }
+
+ protected final class DetailsProvider extends SearchableDataProvider<Misaligned> {
+
+ private static final long serialVersionUID = -1500081449932597854L;
+
+ private final SortableDataProviderComparator<Misaligned> comparator;
+
+ private DetailsProvider() {
+ super(ROWS);
+ setSort("name", SortOrder.ASCENDING);
+ comparator = new SortableDataProviderComparator<>(this);
+ }
+
+ @Override
+ public Iterator<Misaligned> iterator(final long first, final long count) {
+ Collections.sort(misaligned, comparator);
+ return misaligned.subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ @Override
+ public long size() {
+ return misaligned.size();
+ }
+
+ @Override
+ public IModel<Misaligned> model(final Misaligned object) {
+ return new CompoundPropertyModel<>(object);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
new file mode 100644
index 0000000..1ac8c9a
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ReconciliationWidget.java
@@ -0,0 +1,532 @@
+/*
+ * 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 de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SearchableDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
+import org.apache.syncope.client.console.rest.BaseRestClient;
+import org.apache.syncope.client.console.rest.ReportRestClient;
+import org.apache.syncope.client.console.wicket.ajax.markup.html.IndicatorAjaxLink;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.client.console.widgets.reconciliation.Any;
+import org.apache.syncope.client.console.widgets.reconciliation.Anys;
+import org.apache.syncope.client.console.widgets.reconciliation.Misaligned;
+import org.apache.syncope.client.console.widgets.reconciliation.Missing;
+import org.apache.syncope.client.console.widgets.reconciliation.ReconciliationReport;
+import org.apache.syncope.client.console.widgets.reconciliation.ReconciliationReportParser;
+import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.common.lib.to.ExecTO;
+import org.apache.syncope.common.lib.to.JobTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.wicket.Application;
+import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.Component;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
+import org.apache.wicket.extensions.markup.html.tabs.ITab;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Fragment;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.WebSocketPushBroadcaster;
+import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
+import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
+import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
+import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReconciliationWidget extends AbstractWidget {
+
+ private static final long serialVersionUID = -816175678514035085L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(ReconciliationWidget.class);
+
+ private static final long RECONCILIATION_REPORT_KEY = 2L;
+
+ private static final int ROWS = 10;
+
+ private final BaseModal<Any> detailsModal = new BaseModal<>("detailsModal");
+
+ private final PageReference pageRef;
+
+ private final ReportRestClient restClient = new ReportRestClient();
+
+ private final WebMarkupContainer overlay;
+
+ private boolean checkReconciliationJob = false;
+
+ public ReconciliationWidget(final String id, final PageReference pageRef) {
+ super(id);
+ this.pageRef = pageRef;
+ setOutputMarkupId(true);
+ add(detailsModal);
+
+ overlay = new WebMarkupContainer("overlay");
+ overlay.setOutputMarkupPlaceholderTag(true);
+ overlay.setVisible(false);
+ add(overlay);
+
+ ReportTO reconciliationReport = restClient.read(RECONCILIATION_REPORT_KEY);
+
+ Fragment reportResult = reconciliationReport.getExecutions().isEmpty()
+ ? new Fragment("reportResult", "noExecFragment", this)
+ : buildExecFragment();
+ reportResult.setOutputMarkupId(true);
+ add(reportResult);
+
+ add(new WebSocketBehavior() {
+
+ private static final long serialVersionUID = 3507933905864454312L;
+
+ @Override
+ protected void onConnect(final ConnectedMessage message) {
+ super.onConnect(message);
+
+ SyncopeConsoleSession.get().scheduleAtFixedRate(
+ new ReconciliationJobInfoUpdater(message), 0, 10, TimeUnit.SECONDS);
+ }
+ });
+
+ add(new IndicatorAjaxLink<Void>("refresh") {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ try {
+ restClient.startExecution(RECONCILIATION_REPORT_KEY, null);
+
+ overlay.setVisible(true);
+ target.add(ReconciliationWidget.this);
+
+ synchronized (this) {
+ checkReconciliationJob = true;
+ }
+
+ info(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (Exception e) {
+ LOG.error("While starting reconciliation report", e);
+ error("Could not start reconciliation report");
+ }
+ SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+ }
+ });
+ }
+
+ private Fragment buildExecFragment() {
+ Fragment execFragment = new Fragment("reportResult", "execFragment", this);
+ execFragment.setOutputMarkupId(true);
+
+ Pair<List<ProgressBean>, ReconciliationReport> execResult;
+ try {
+ execResult = parseReconciliationReportExec();
+ } catch (Exception e) {
+ LOG.error("Could not parse the reconciliation report result", e);
+ execResult = Pair.of(Collections.<ProgressBean>emptyList(), null);
+ }
+ final List<ProgressBean> progressBeans = execResult.getLeft();
+ final ReconciliationReport report = execResult.getRight();
+
+ List<ITab> tabs = new ArrayList<>();
+ tabs.add(new AbstractTab(new ResourceModel("summary")) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new ProgressesPanel(panelId, report.getRun(), progressBeans);
+ }
+ });
+ tabs.add(new AbstractTab(new ResourceModel("users")) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new AnysReconciliationPanel(panelId, report.getUsers(), pageRef);
+ }
+ });
+ tabs.add(new AbstractTab(new ResourceModel("groups")) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new AnysReconciliationPanel(panelId, report.getGroups(), pageRef);
+ }
+ });
+ for (final Anys anys : report.getAnyObjects()) {
+ tabs.add(new AbstractTab(Model.of(anys.getAnyType())) {
+
+ private static final long serialVersionUID = -6815067322125799251L;
+
+ @Override
+ public Panel getPanel(final String panelId) {
+ return new AnysReconciliationPanel(panelId, anys, pageRef);
+ }
+ });
+ }
+
+ execFragment.add(new AjaxBootstrapTabbedPanel<>("execResult", tabs));
+
+ return execFragment;
+ }
+
+ private Pair<List<ProgressBean>, ReconciliationReport> parseReconciliationReportExec() throws IOException {
+ List<ProgressBean> beans = Collections.emptyList();
+ ReconciliationReport report = null;
+
+ ExecTO exec = IterableUtils.find(restClient.listRecentExecutions(ROWS), new Predicate<ExecTO>() {
+
+ @Override
+ public boolean evaluate(final ExecTO exec) {
+ return exec.getRefKey() == RECONCILIATION_REPORT_KEY;
+ }
+ });
+ if (exec == null) {
+ LOG.error("Could not find the last execution of reconciliation report");
+ } else {
+ Object entity = restClient.exportExecutionResult(exec.getKey(), ReportExecExportFormat.XML).getEntity();
+ if (entity instanceof InputStream) {
+ try {
+ report = ReconciliationReportParser.parse(exec.getEnd(), (InputStream) entity);
+
+ beans = new ArrayList<>();
+
+ ProgressBean progressBean = new ProgressBean();
+ progressBean.setText(getString("users"));
+ progressBean.setTotal(report.getUsers().getTotal());
+ progressBean.setFraction(report.getUsers().getTotal() - report.getUsers().getAnys().size());
+ progressBean.setCssClass("progress-bar-yellow");
+ beans.add(progressBean);
+
+ progressBean = new ProgressBean();
+ progressBean.setText(getString("groups"));
+ progressBean.setTotal(report.getGroups().getTotal());
+ progressBean.setFraction(report.getGroups().getTotal() - report.getGroups().getAnys().size());
+ progressBean.setCssClass("progress-bar-red");
+ beans.add(progressBean);
+
+ int i = 0;
+ for (Anys anys : report.getAnyObjects()) {
+ progressBean = new ProgressBean();
+ progressBean.setText(anys.getAnyType());
+ progressBean.setTotal(anys.getTotal());
+ progressBean.setFraction(anys.getTotal() - anys.getAnys().size());
+ progressBean.setCssClass("progress-bar-" + (i % 2 == 0 ? "green" : "aqua"));
+ beans.add(progressBean);
+
+ i++;
+ }
+ } catch (Exception e) {
+ LOG.error("Could not parse the last execution available of reconciliation report", e);
+ }
+ }
+ }
+
+ return Pair.of(beans, report);
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof WebSocketPushPayload) {
+ WebSocketPushPayload wsEvent = (WebSocketPushPayload) event.getPayload();
+ if (wsEvent.getMessage() instanceof ReconciliationJobNotRunningMessage) {
+ overlay.setVisible(false);
+
+ addOrReplace(buildExecFragment());
+
+ wsEvent.getHandler().add(ReconciliationWidget.this);
+
+ synchronized (this) {
+ checkReconciliationJob = false;
+ }
+ }
+ }
+ }
+
+ private class AnysReconciliationPanel extends AbstractSearchResultPanel<
+ Any, Any, AnysReconciliationProvider, BaseRestClient> {
+
+ private static final long serialVersionUID = -8214546246301342868L;
+
+ private final Anys anys;
+
+ AnysReconciliationPanel(final String id, final Anys anys, final PageReference pageRef) {
+ super(id, new Builder<Any, Any, BaseRestClient>(null, pageRef) {
+
+ private static final long serialVersionUID = 8769126634538601689L;
+
+ @Override
+ protected WizardMgtPanel<Any> newInstance(final String id) {
+ return new AnysReconciliationPanel(id, anys, pageRef);
+ }
+ }.disableCheckBoxes().hidePaginator());
+
+ this.anys = anys;
+ this.rows = ROWS;
+ initResultTable();
+ }
+
+ @Override
+ protected AnysReconciliationProvider dataProvider() {
+ return new AnysReconciliationProvider(anys);
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBulkActions() {
+ return Collections.<ActionLink.ActionType>emptyList();
+ }
+
+ @Override
+ protected List<IColumn<Any, String>> getColumns() {
+ List<IColumn<Any, String>> columns = new ArrayList<>();
+
+ columns.add(new AbstractColumn<Any, String>(new ResourceModel("reference"), "key") {
+
+ private static final long serialVersionUID = -1822504503325964706L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<Any>> cellItem,
+ final String componentId,
+ final IModel<Any> rowModel) {
+
+ cellItem.add(new Label(componentId,
+ rowModel.getObject().getKey()
+ + (StringUtils.isBlank(rowModel.getObject().getName())
+ ? StringUtils.EMPTY
+ : " " + rowModel.getObject().getName())));
+ }
+ });
+
+ final Set<String> resources = new HashSet<>();
+ for (Any any : anys.getAnys()) {
+ resources.addAll(CollectionUtils.collect(any.getMissing(), new Transformer<Missing, String>() {
+
+ @Override
+ public String transform(final Missing input) {
+ return input.getResource();
+ }
+ }));
+ resources.addAll(CollectionUtils.collect(any.getMisaligned(), new Transformer<Misaligned, String>() {
+
+ @Override
+ public String transform(final Misaligned input) {
+ return input.getResource();
+ }
+ }));
+ }
+ for (final String resource : resources) {
+ columns.add(new AbstractColumn<Any, String>(Model.of(resource)) {
+
+ private static final long serialVersionUID = -1822504503325964706L;
+
+ @Override
+ public void populateItem(
+ final Item<ICellPopulator<Any>> cellItem,
+ final String componentId,
+ final IModel<Any> rowModel) {
+
+ final Any any = rowModel.getObject();
+
+ Missing missing = IterableUtils.find(any.getMissing(), new Predicate<Missing>() {
+
+ @Override
+ public boolean evaluate(final Missing object) {
+ return resource.equals(object.getResource());
+ }
+ });
+ final List<Misaligned> misaligned = CollectionUtils.select(
+ any.getMisaligned(), new Predicate<Misaligned>() {
+
+ @Override
+ public boolean evaluate(final Misaligned object) {
+ return resource.equals(object.getResource());
+ }
+ }, new ArrayList<Misaligned>());
+ Component content = missing == null
+ ? misaligned == null || misaligned.isEmpty()
+ ? new Label(componentId, StringUtils.EMPTY)
+ : ActionLinksPanel.<Any>builder().add(new ActionLink<Any>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final Any ignore) {
+ modal.header(Model.of(
+ rowModel.getObject().getType()
+ + " " + rowModel.getObject().getKey()
+ + " " + rowModel.getObject().getName()));
+ modal.setContent(new ReconciliationDetailsModalPanel(
+ modal,
+ resource,
+ misaligned,
+ ReconciliationWidget.this.pageRef));
+ modal.show(true);
+ target.add(modal);
+ }
+ }, ActionLink.ActionType.VIEW).
+ build(componentId)
+ : ActionLinksPanel.<Any>builder().add(null, ActionLink.ActionType.NOT_FOND).
+ build(componentId);
+ cellItem.add(content);
+ cellItem.add(new AttributeModifier("class", "text-center"));
+ }
+ });
+ }
+
+ return columns;
+ }
+ }
+
+ protected final class AnysReconciliationProvider extends SearchableDataProvider<Any> {
+
+ private static final long serialVersionUID = -1500081449932597854L;
+
+ private final Anys anys;
+
+ private final SortableDataProviderComparator<Any> comparator;
+
+ private AnysReconciliationProvider(final Anys anys) {
+ super(ROWS);
+ this.anys = anys;
+ setSort("key", SortOrder.ASCENDING);
+ comparator = new SortableDataProviderComparator<>(this);
+ }
+
+ @Override
+ public Iterator<Any> iterator(final long first, final long count) {
+ Collections.sort(anys.getAnys(), comparator);
+ return anys.getAnys().subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ @Override
+ public long size() {
+ return anys.getAnys().size();
+ }
+
+ @Override
+ public IModel<Any> model(final Any object) {
+ return new CompoundPropertyModel<>(object);
+ }
+ }
+
+ protected final class ReconciliationJobInfoUpdater implements Runnable {
+
+ private final String applicationName;
+
+ private final SyncopeConsoleSession session;
+
+ private final IKey key;
+
+ public ReconciliationJobInfoUpdater(final ConnectedMessage message) {
+ this.applicationName = message.getApplication().getName();
+ this.session = SyncopeConsoleSession.get();
+ this.key = message.getKey();
+ }
+
+ @Override
+ public void run() {
+ synchronized (ReconciliationWidget.this) {
+ if (ReconciliationWidget.this.checkReconciliationJob) {
+ try {
+ Application application = Application.get(applicationName);
+ ThreadContext.setApplication(application);
+ ThreadContext.setSession(session);
+
+ JobTO reportJobTO = IterableUtils.find(session.getService(ReportService.class).listJobs(),
+ new Predicate<JobTO>() {
+
+ @Override
+ public boolean evaluate(final JobTO jobTO) {
+ return RECONCILIATION_REPORT_KEY == jobTO.getRefKey();
+ }
+ });
+ if (reportJobTO != null && !reportJobTO.isRunning()) {
+ LOG.debug("Report {} is not running", RECONCILIATION_REPORT_KEY);
+
+ WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
+ WebSocketPushBroadcaster broadcaster =
+ new WebSocketPushBroadcaster(webSocketSettings.getConnectionRegistry());
+ broadcaster.broadcast(
+ new ConnectedMessage(application, session.getId(), key),
+ new ReconciliationJobNotRunningMessage());
+ }
+ } catch (Throwable t) {
+ LOG.error("Unexpected error while checking for updated reconciliation job info", t);
+ } finally {
+ ThreadContext.detach();
+ }
+ }
+ }
+ }
+ }
+
+ private static class ReconciliationJobNotRunningMessage implements IWebSocketPushMessage, Serializable {
+
+ private static final long serialVersionUID = -824793424112532838L;
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java
new file mode 100644
index 0000000..5e915b4
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Any.java
@@ -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.syncope.client.console.widgets.reconciliation;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class Any extends AbstractBaseBean {
+
+ private static final long serialVersionUID = 2421645848049271898L;
+
+ private String type;
+
+ private long key;
+
+ private String name;
+
+ private final List<Missing> missing = new ArrayList<>();
+
+ private final List<Misaligned> misaligned = new ArrayList<>();
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public long getKey() {
+ return key;
+ }
+
+ public void setKey(final long key) {
+ this.key = key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public List<Missing> getMissing() {
+ return missing;
+ }
+
+ public List<Misaligned> getMisaligned() {
+ return misaligned;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java
new file mode 100644
index 0000000..fecdfee
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Anys.java
@@ -0,0 +1,55 @@
+/*
+ * 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.reconciliation;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class Anys extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -2482591351364634179L;
+
+ private int total = 0;
+
+ private String anyType;
+
+ private final List<Any> anys = new ArrayList<>();
+
+ public int getTotal() {
+ return total;
+ }
+
+ public void setTotal(final int total) {
+ this.total = total;
+ }
+
+ public String getAnyType() {
+ return anyType;
+ }
+
+ public void setAnyType(final String anyType) {
+ this.anyType = anyType;
+ }
+
+ public List<Any> getAnys() {
+ return anys;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java
new file mode 100644
index 0000000..bd189e6
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Misaligned.java
@@ -0,0 +1,51 @@
+/*
+ * 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.reconciliation;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class Misaligned extends Missing {
+
+ private static final long serialVersionUID = -2287634884015557714L;
+
+ private final String name;
+
+ private final Set<String> onSyncope = new HashSet<>();
+
+ private final Set<String> onResource = new HashSet<>();
+
+ public Misaligned(final String resource, final String connObjectKeyValue, final String name) {
+ super(resource, connObjectKeyValue);
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Set<String> getOnSyncope() {
+ return onSyncope;
+ }
+
+ public Set<String> getOnResource() {
+ return onResource;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java
new file mode 100644
index 0000000..2d0254a
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/Missing.java
@@ -0,0 +1,44 @@
+/*
+ * 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.reconciliation;
+
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class Missing extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -4779715117027316991L;
+
+ private final String resource;
+
+ private final String connObjectKeyValue;
+
+ public Missing(final String resource, final String connObjectKeyValue) {
+ this.resource = resource;
+ this.connObjectKeyValue = connObjectKeyValue;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public String getConnObjectKeyValue() {
+ return connObjectKeyValue;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java
new file mode 100644
index 0000000..b107426
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReport.java
@@ -0,0 +1,66 @@
+/*
+ * 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.reconciliation;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+public class ReconciliationReport extends AbstractBaseBean {
+
+ private static final long serialVersionUID = 931063230006747313L;
+
+ private final Date run;
+
+ private Anys users;
+
+ private Anys groups;
+
+ private final List<Anys> anyObjects = new ArrayList<>();
+
+ public ReconciliationReport(final Date run) {
+ this.run = run;
+ }
+
+ public Date getRun() {
+ return run == null ? null : new Date(run.getTime());
+ }
+
+ public Anys getUsers() {
+ return users;
+ }
+
+ public void setUsers(final Anys users) {
+ this.users = users;
+ }
+
+ public Anys getGroups() {
+ return groups;
+ }
+
+ public void setGroups(final Anys groups) {
+ this.groups = groups;
+ }
+
+ public List<Anys> getAnyObjects() {
+ return anyObjects;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java
new file mode 100644
index 0000000..c99b7e3
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java
@@ -0,0 +1,192 @@
+/*
+ * 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.reconciliation;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+public final class ReconciliationReportParser {
+
+ private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance();
+
+ public static ReconciliationReport parse(final Date run, final InputStream in) throws XMLStreamException {
+ XMLStreamReader streamReader = INPUT_FACTORY.createXMLStreamReader(in);
+ streamReader.nextTag(); // root
+ streamReader.nextTag(); // report
+ streamReader.nextTag(); // reportlet
+
+ ReconciliationReport report = new ReconciliationReport(run);
+
+ List<Missing> missing = new ArrayList<>();
+ List<Misaligned> misaligned = new ArrayList<>();
+ Set<String> onSyncope = null;
+ Set<String> onResource = null;
+
+ Any user = null;
+ Any group = null;
+ Any anyObject = null;
+ String lastAnyType = null;
+ while (streamReader.hasNext()) {
+ if (streamReader.isStartElement()) {
+ switch (streamReader.getLocalName()) {
+ case "users":
+ Anys users = new Anys();
+ users.setTotal(Integer.valueOf(streamReader.getAttributeValue("", "total")));
+ report.setUsers(users);
+ break;
+
+ case "user":
+ user = new Any();
+ user.setType(AnyTypeKind.USER.name());
+ user.setKey(Long.valueOf(streamReader.getAttributeValue("", "key")));
+ user.setName(streamReader.getAttributeValue("", "username"));
+ report.getUsers().getAnys().add(user);
+ break;
+
+ case "groups":
+ Anys groups = new Anys();
+ groups.setTotal(Integer.valueOf(streamReader.getAttributeValue("", "total")));
+ report.setGroups(groups);
+ break;
+
+ case "group":
+ group = new Any();
+ group.setType(AnyTypeKind.GROUP.name());
+ group.setKey(Long.valueOf(streamReader.getAttributeValue("", "key")));
+ group.setName(streamReader.getAttributeValue("", "groupName"));
+ report.getGroups().getAnys().add(group);
+ break;
+
+ case "anyObjects":
+ lastAnyType = streamReader.getAttributeValue("", "type");
+ Anys anyObjects = new Anys();
+ anyObjects.setAnyType(lastAnyType);
+ anyObjects.setTotal(Integer.valueOf(streamReader.getAttributeValue("", "total")));
+ report.getAnyObjects().add(anyObjects);
+ break;
+
+ case "anyObject":
+ anyObject = new Any();
+ anyObject.setType(lastAnyType);
+ anyObject.setKey(Long.valueOf(streamReader.getAttributeValue("", "key")));
+ final String anyType = lastAnyType;
+ IterableUtils.find(report.getAnyObjects(), new Predicate<Anys>() {
+
+ @Override
+ public boolean evaluate(final Anys anys) {
+ return anyType.equals(anys.getAnyType());
+ }
+ }).getAnys().add(anyObject);
+ break;
+
+ case "missing":
+ missing.add(new Missing(
+ streamReader.getAttributeValue("", "resource"),
+ streamReader.getAttributeValue("", "connObjectKeyValue")));
+ break;
+
+ case "misaligned":
+ misaligned.add(new Misaligned(
+ streamReader.getAttributeValue("", "resource"),
+ streamReader.getAttributeValue("", "connObjectKeyValue"),
+ streamReader.getAttributeValue("", "name")));
+ break;
+
+ case "onSyncope":
+ onSyncope = new HashSet<>();
+ break;
+
+ case "onResource":
+ onResource = new HashSet<>();
+ break;
+
+ case "value":
+ Set<String> set = onSyncope == null ? onResource : onSyncope;
+ set.add(streamReader.getElementText());
+ break;
+
+ default:
+ }
+ } else if (streamReader.isEndElement()) {
+ switch (streamReader.getLocalName()) {
+ case "user":
+ user.getMissing().addAll(missing);
+ user.getMisaligned().addAll(misaligned);
+ missing.clear();
+ misaligned.clear();
+ break;
+
+ case "group":
+ group.getMissing().addAll(missing);
+ group.getMisaligned().addAll(misaligned);
+ missing.clear();
+ misaligned.clear();
+ break;
+
+ case "anyObject":
+ anyObject.getMissing().addAll(missing);
+ anyObject.getMisaligned().addAll(misaligned);
+ missing.clear();
+ misaligned.clear();
+ break;
+
+ case "onSyncope":
+ misaligned.get(misaligned.size() - 1).getOnSyncope().addAll(onSyncope);
+ onSyncope = null;
+ break;
+
+ case "onResource":
+ misaligned.get(misaligned.size() - 1).getOnResource().addAll(onResource);
+ onResource = null;
+ break;
+
+ default:
+ }
+
+ }
+
+ streamReader.next();
+ }
+
+ try {
+ System.out.println("QQQQQQQQQ\n" + new ObjectMapper().writeValueAsString(report));
+ } catch (JsonProcessingException ex) {
+ System.err.println("nuuuuuuuuuuuuuuuuuuuuuuuu");
+ ex.printStackTrace();
+ }
+
+ return report;
+ }
+
+ private ReconciliationReportParser() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
index dc883bf..59bb335 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
@@ -19,8 +19,8 @@
package org.apache.syncope.client.console.wizards;
import java.io.Serializable;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.panels.ModalPanel;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -87,7 +87,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
send(AjaxWizard.this, Broadcast.BUBBLE, new NewItemCancelEvent<>(item, target));
} catch (Exception e) {
LOG.warn("Wizard error on cancel", e);
- error(getString(Constants.ERROR) + ": " + e.getMessage());
+ error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
}
}
@@ -103,7 +103,7 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard implemen
send(AjaxWizard.this, Broadcast.BUBBLE, new NewItemFinishEvent<>(item, target).setResult(res));
} catch (Exception e) {
LOG.error("Wizard error on finish", e);
- error(getString(Constants.ERROR) + ": " + e.getMessage());
+ error(StringUtils.isBlank(e.getMessage()) ? e.getClass().getName() : e.getMessage());
SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
index 6d295f7..34dc4a3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/WizardMgtPanel.java
@@ -82,9 +82,9 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
/**
* Modal window.
*/
- protected final BaseModal<T> altDefaultModal = new BaseModal<T>("alternativeDefaultModal");
+ protected final BaseModal<T> altDefaultModal = new BaseModal<>("alternativeDefaultModal");
- protected final BaseModal<T> displayAttributeModal = new BaseModal<T>("displayAttributeModal");
+ protected final BaseModal<T> displayAttributeModal = new BaseModal<>("displayAttributeModal");
protected WizardMgtPanel(final String id) {
this(id, false);
@@ -166,10 +166,9 @@ public abstract class WizardMgtPanel<T extends Serializable> extends Panel imple
if (wizardInModal && showResultPage) {
modal.setContent(new ResultPage<T>(
item,
- AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult(),
- pageRef) {
+ AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult()) {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = -2630573849050255233L;
@Override
protected void closeAction(final AjaxRequestTarget target) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index fafdfb0..fc2a941 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.console.wizards.any;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -153,7 +154,7 @@ public class Relationships extends WizardStep {
}
});
- viewFragment.add(ActionLinksPanel.<RelationshipTO>builder(pageRef).add(new ActionLink<RelationshipTO>() {
+ viewFragment.add(ActionLinksPanel.<RelationshipTO>builder().add(new ActionLink<RelationshipTO>() {
private static final long serialVersionUID = 3257738274365467945L;
@@ -192,9 +193,7 @@ public class Relationships extends WizardStep {
}
private void addNewRelationships(final RelationshipTO... rels) {
- for (RelationshipTO relationship : rels) {
- getCurrentRelationships().add(relationship);
- }
+ getCurrentRelationships().addAll(Arrays.asList(rels));
}
private void removeRelationships(
@@ -330,7 +329,7 @@ public class Relationships extends WizardStep {
anyObjectSearchPanel = new AnyObjectSearchPanel.Builder(
anyType.getKey(),
- new ListModel<SearchClause>(new ArrayList<SearchClause>())).
+ new ListModel<>(new ArrayList<SearchClause>())).
enableSearch().
build("searchPanel");
fragment.add(anyObjectSearchPanel.setRenderBodyOnly(true));
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
index 060a027..45b4aa3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/ResultPage.java
@@ -23,7 +23,6 @@ import org.apache.syncope.client.console.panels.ModalPanel;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
@@ -38,14 +37,14 @@ public abstract class ResultPage<T extends Serializable> extends Panel implement
private final T item;
- public ResultPage(final T item, final Serializable result, final PageReference pageRef) {
+ public ResultPage(final T item, final Serializable result) {
super(BaseModal.CONTENT_ID);
setOutputMarkupId(true);
this.item = item;
add(customResultBody("customResultBody", item, result));
- add(ActionLinksPanel.<T>builder(pageRef).add(new ActionLink<T>() {
+ add(ActionLinksPanel.<T>builder().add(new ActionLink<T>() {
private static final long serialVersionUID = 3257738274365467945L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
index bfb194b..14d1d24 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/StatusPanel.java
@@ -177,7 +177,7 @@ public class StatusPanel extends Panel {
public void onClick(final AjaxRequestTarget target, final StatusBean bean) {
mlp.next(bean.getResourceName(), new RemoteObjectPanel(bean, connObjects), target);
}
- }, ActionLink.ActionType.SEARCH, StandardEntitlement.RESOURCE_GET_CONNOBJECT);
+ }, ActionLink.ActionType.VIEW, StandardEntitlement.RESOURCE_GET_CONNOBJECT);
listViewPanel = ListViewPanel.class.cast(builder.build(MultilevelPanel.FIRST_LEVEL_ID));
mlp.setFirstLevel(listViewPanel);
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 0f71eeb..c3940eb 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -531,3 +531,13 @@ END - Result page
.nav-tabs-custom > .nav-tabs > li.active {
border-top-color: #d2d6de !important;
}
+
+.code-deletion {
+ background-color: #ffdddd;
+ border-color: #f1c0c0;
+}
+
+.code-addition {
+ background-color: #dbffdb;
+ border-color: #c1e9c1;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
index 200d752..e2c5948 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Realms.html
@@ -17,23 +17,34 @@ specific language governing permissions and limitations
under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <wicket:head>
+ <script type="text/javascript">
+ $(document).ready(function () {
+ $("#pageTitleInBradcrumb").append($("#pageTitle").text());
+ });
+ </script>
+ </wicket:head>
<wicket:extend>
+ <script lang="text/javascript">
+
+ </script>
<section class="content-header">
<h1> </h1>
<ol class="breadcrumb">
<li><a wicket:id="dashboardBr"><i class="fa fa-dashboard"></i> <wicket:message key="dashboard"/></a></li>
- <li class="active"><wicket:message key="realms"/></li>
+ <li class="active" id="pageTitleInBradcrumb"/>
</ol>
+ <div id="pageTitle" style="visibility: hidden;"><wicket:message key='realms'/></div>
</section>
<section class="content" wicket:id="content">
<div class="box">
<div class="box-body">
- <span wicket:id="realmChoicePanel">[Realm Sidebar Panel]</span>
- <wicket:container wicket:id="body"></wicket:container>
+ <span wicket:id="realmChoicePanel"/>
+ <wicket:container wicket:id="body"/>
</div>
</div>
- <div wicket:id="modal"></div>
+ <div wicket:id="modal"/>
</section>
</wicket:extend>
</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
index ae731af..bc6f762 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/DashboardControlPanel.html
@@ -23,5 +23,11 @@ under the License.
<span wicket:id="job"/>
</div>
</div>
+
+ <div class="row">
+ <div class="col-md-12">
+ <span wicket:id="reconciliation"/>
+ </div>
+ </div>
</wicket:panel>
</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
index 4b6bc36..3550ace 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ParametersPanel.html
@@ -18,6 +18,6 @@ under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:extend>
- <div wicket:id="modalDetails" />
+ <div wicket:id="modalDetails"/>
</wicket:extend>
</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
index 9cbe6ba..cb02567 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/WorkflowTogglePanel.html
@@ -17,33 +17,30 @@ specific language governing permissions and limitations
under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
- <head><title>toggle menu</title></head>
- <body>
- <wicket:head>
- <script type="text/javascript">
- $(document).ready(function () {
- $("div.inactive-topology-menu").toggle("slow");
- $("div.inactive-topology-menu").attr("class", "topology-menu active-topology-menu");
- });
- </script>
+ <wicket:head>
+ <script type="text/javascript">
+ $(document).ready(function () {
+ $("div.inactive-topology-menu").toggle("slow");
+ $("div.inactive-topology-menu").attr("class", "topology-menu active-topology-menu");
+ });
+ </script>
- <style type="text/css">
- div.topology-menu {
- top: 65px !important;
- }
+ <style type="text/css">
+ div.topology-menu {
+ top: 65px !important;
+ }
- div.topology-menu div.header {
- display: none !important;
- }
- </style>
- </wicket:head>
- <wicket:extend>
- <div wicket:id="container">
- <ul class="menu">
- <li><i class="fa fa-file-image-o"></i><a href="#" wicket:id="activitiModeler">Activiti Modeler</a></li>
- <li><i class="fa fa-file-text-o"></i><a href="#" wicket:id="xmlEditor">XML editor</a></li>
- </ul>
- </div>
- </wicket:extend>
- </body>
+ div.topology-menu div.header {
+ display: none !important;
+ }
+ </style>
+ </wicket:head>
+ <wicket:extend>
+ <div wicket:id="container">
+ <ul class="menu">
+ <li><i class="fa fa-file-image-o"></i><a href="#" wicket:id="activitiModeler">Activiti Modeler</a></li>
+ <li><i class="fa fa-file-text-o"></i><a href="#" wicket:id="xmlEditor">XML editor</a></li>
+ </ul>
+ </div>
+ </wicket:extend>
</html>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
index 8829644..78d0927 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
@@ -34,6 +34,8 @@ under the License.
<span wicket:id="panelExecute">[plus]</span>
<span wicket:id="panelEnable">[plus]</span>
<span wicket:id="panelSearch">[plus]</span>
+ <span wicket:id="panelNotFound">[plus]</span>
+ <span wicket:id="panelView">[plus]</span>
<span wicket:id="panelMapping">[plus]</span>
<span wicket:id="panelAccountLink">[plus]</span>
<span wicket:id="panelResetTime">[plus]</span>
@@ -96,6 +98,14 @@ under the License.
<a href="#" wicket:id="createLink" class="btn"><i class="glyphicon glyphicon-plus" alt="create icon" title="Create"></i></a>
</wicket:fragment>
+ <wicket:fragment wicket:id="fragmentNotFound">
+ <i class="fa fa-eye-slash" alt="notFound icon" title="Not Found"></i>
+ </wicket:fragment>
+
+ <wicket:fragment wicket:id="fragmentView">
+ <a href="#" wicket:id="viewLink" class="btn"><i class="fa fa-eye" alt="view icon" title="View"></i></a>
+ </wicket:fragment>
+
<wicket:fragment wicket:id="fragmentSearch">
<a href="#" wicket:id="searchLink" class="btn"><i class="glyphicon glyphicon-search" alt="search icon" title="Search"></i></a>
</wicket:fragment>
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/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 c2f9ce3..a476bc2 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,7 +18,7 @@ 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 box-default box-solid">
<div class="box-header with-border">
<h3 class="box-title"><wicket:message key="usersGroupsAndAnyObjectsDistribution"/></h3>
<div class="box-tools pull-right">
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/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
index acc12b3..2e48d08 100644
--- 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
@@ -18,7 +18,7 @@ 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 box-default box-solid">
<div class="box-header with-border">
<h3 class="box-title"><wicket:message key="configurationStatus"/></h3>
<div class="box-tools pull-right">
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
index bc19be2..fdf5373 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.html
@@ -18,20 +18,16 @@ under the License.
-->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<wicket:panel>
- <div class="nav-tabs-custom">
- <ul class="nav nav-tabs pull-right ui-sortable-handle">
- <li class="active"><a data-toggle="tab" href="#running">Available</a></li>
- <li><a data-toggle="tab" href="#recent">Recent</a></li>
- <li class="pull-left header"><i class="fa fa-gears"></i> Jobs</li>
- </ul>
- <div class="tab-content no-padding">
- <div style="position: relative;" id="running" class="chart tab-pane active">
- <span wicket:id="available"/>
- </div>
- <div style="position: relative;" id="recent" class="chart tab-pane">
- <span wicket:id="recent"/>
+ <div class="box box-default box-solid">
+ <div class="box-header with-border">
+ <h3 class="box-title"><wicket:message key="jobs"/></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="box-body" wicket:id="tabbedPanel"/>
+ </div>
</div>
</wicket:panel>
</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
index 35dbb2e..273253a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget.properties
@@ -20,3 +20,6 @@ scheduled=Scheduled
start=Start
message=Message
end=End
+available=Available
+recent=Recent
+jobs=Jobs
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
index 3738c3c..19a26b9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_it.properties
@@ -20,3 +20,6 @@ scheduled=Programmato
start=Inizio
message=Messaggio
end=Fine
+available=Disponibili
+recent=Recenti
+jobs=Job
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
index 02411ab..e300f11 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/JobWidget_pt_BR.properties
@@ -20,3 +20,6 @@ scheduled=Programado
start=Come\u00e7o
message=Mensagem
end=Final
+available=Dispon\u00edvel
+recent=Recente
+jobs=Job
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/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 d6a4260..8ce2e9f 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,7 +18,7 @@ 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 box-default box-solid">
<div class="box-header with-border">
<h3 class="box-title"><wicket:message key="systemLoad"/></h3>
<div class="box-tools pull-right">
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html
new file mode 100644
index 0000000..98550e5
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressPanel.html
@@ -0,0 +1,30 @@
+<!--
+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="progress-group">
+ <span class="progress-text" wicket:id="text"></span>
+ <span class="progress-number"><b><span wicket:id="fraction"/></b>/<span wicket:id="total"/></span>
+
+ <div class="progress sm">
+ <div wicket:id="progress" class="progress-bar progress-bar-striped"></div>
+ </div>
+ </div>
+ </wicket:panel>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html
new file mode 100644
index 0000000..7aba758
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.html
@@ -0,0 +1,24 @@
+<!--
+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="text-right"><em><wicket:message key="lastUpdateMsg"/>: <span wicket:id="lastUpdate"/></em></div><br/>
+ <span wicket:id="progresses"><span wicket:id="progress"/></span>
+ </wicket:panel>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties
new file mode 100644
index 0000000..41f94c6
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel.properties
@@ -0,0 +1,17 @@
+# 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.
+lastUpdateMsg=Last Update
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties
new file mode 100644
index 0000000..c32f22c
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_it.properties
@@ -0,0 +1,17 @@
+# 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.
+lastUpdateMsg=Ultimo Aggiornamento
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties
new file mode 100644
index 0000000..878c519
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ProgressesPanel_pt_BR.properties
@@ -0,0 +1,17 @@
+# 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.
+lastUpdateMsg=\u00daltima Atualiza\u00e7\u00e3o
http://git-wip-us.apache.org/repos/asf/syncope/blob/f9f50c57/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html
new file mode 100644
index 0000000..645039d
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ReconciliationDetailsModalPanel.html
@@ -0,0 +1,23 @@
+<!--
+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:extend>
+ <div wicket:id="diff"/>
+ </wicket:extend>
+</html>