[SYNCOPE-156] merge from master + connector and resource modal re-work. Still 
re-working on provisions and mappings


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

Branch: refs/heads/master
Commit: b56c08eebf369416d4418b607c80691ca47b55e4
Parents: 6f67940 5dc5191
Author: fmartelli <[email protected]>
Authored: Tue Sep 29 15:44:47 2015 +0200
Committer: fmartelli <[email protected]>
Committed: Tue Sep 29 15:44:47 2015 +0200

----------------------------------------------------------------------
 archetype/pom.xml                               |  20 +
 .../client/cli/commands/ReportCommand.java      |   3 +-
 .../panels/AbstractConnectorConfPanel.java      | 114 +++++
 .../console/panels/AbstractResourceModal.java   |  45 +-
 .../panels/ConnectorCapabilitiesPanel.java      |  58 +++
 .../console/panels/ConnectorConfPanel.java      |  86 ++++
 .../console/panels/ConnectorDetailsPanel.java   | 197 ++++++++
 .../client/console/panels/ConnectorModal.java   | 452 ++++-------------
 .../client/console/panels/ListViewPanel.java    |  10 +-
 .../console/panels/ResourceConnConfPanel.java   | 122 +----
 .../console/panels/ResourceDetailsPanel.java    | 237 +++------
 .../console/panels/ResourceMappingPanel.java    |  23 -
 .../client/console/panels/ResourceModal.java    |  36 +-
 .../console/panels/ResourceSecurityPanel.java   |  41 +-
 .../client/console/rest/ReportRestClient.java   |  18 +-
 .../client/console/rest/TaskRestClient.java     |   4 +-
 .../syncope/client/console/themes/AdminLTE.java |  14 -
 .../console/topology/TopologyNodePanel.java     |  25 +-
 .../markup/html/bootstrap/dialog/BaseModal.java |   6 +
 .../markup/html/form/AbstractFieldPanel.java    |  68 ++-
 .../markup/html/form/AjaxCheckBoxPanel.java     |  17 +-
 .../html/form/AjaxPasswordFieldPanel.java       |  13 +-
 .../markup/html/form/AjaxTextFieldPanel.java    |   5 +-
 .../wicket/markup/html/form/FieldPanel.java     |  37 +-
 .../markup/html/form/SpinnerFieldPanel.java     |   2 -
 .../wicket/markup/html/list/AltListView.java    |  59 ---
 .../html/list/ConnConfPropertyListView.java     | 109 ++--
 .../provision/ProvisionWizardBuilder.java       |   6 +-
 .../META-INF/resources/css/syncopeConsole.css   |   6 +
 .../panels/AbstractConnectorConfPanel.html      |  38 ++
 .../console/panels/AbstractResourceModal.html   |  23 +
 .../panels/ConnectorCapabilitiesPanel.html      |  28 ++
 .../console/panels/ConnectorDetailsPanel.html   |  61 +++
 .../client/console/panels/ConnectorModal.html   | 147 ------
 .../console/panels/ConnectorModal.properties    |   7 +-
 .../console/panels/ConnectorModal_it.properties |   7 +-
 .../panels/ConnectorModal_pt_BR.properties      |   7 +-
 .../console/panels/ResourceConnConfPanel.html   |  40 --
 .../console/panels/ResourceDetailsPanel.html    |   4 -
 .../client/console/panels/ResourceModal.html    |  23 -
 .../console/panels/ResourceModal.properties     |   5 +-
 .../console/panels/ResourceModal_it.properties  |   2 +-
 .../panels/ResourceModal_pt_BR.properties       |   2 +-
 .../markup/html/form/AbstractFieldPanel.html    |  35 ++
 .../markup/html/form/AjaxCheckBoxPanel.html     |   9 +-
 .../html/form/AjaxDropDownChoicePanel.html      |   1 +
 .../html/form/AjaxPasswordFieldPanel.html       |  17 +-
 .../markup/html/form/AjaxTextFieldPanel.html    |   3 +-
 .../form/CheckBoxMultipleChoiceFieldPanel.html  |  18 +-
 .../wicket/markup/html/form/FieldPanel.html     |  31 --
 .../markup/html/form/MultiFieldPanel.html       |   8 +-
 .../markup/html/form/SpinnerFieldPanel.html     |   1 +
 .../syncope/client/lib/SyncopeClient.java       |  21 +-
 .../lib/builders/AbstractQueryBuilder.java      |  57 +++
 .../lib/builders/AnyListQueryBuilder.java       |   6 +-
 .../client/lib/builders/AnyQueryBuilder.java    |  49 ++
 .../client/lib/builders/ListQueryBuilder.java   |  54 --
 .../client/lib/builders/TaskQueryBuilder.java   |  60 +++
 client/pom.xml                                  |  19 +
 .../syncope/common/lib/to/MappingItemTO.java    |  11 +-
 .../common/lib/to/PropagationTaskTO.java        |  21 +-
 .../syncope/common/lib/to/ResourceTO.java       |  33 +-
 .../apache/syncope/common/lib/to/SyncopeTO.java |   9 +
 .../common/lib/types/ConnectorCapability.java   |   9 +-
 .../common/lib/types/PropagationMode.java       |  29 --
 .../lib/types/PropagationTaskExecStatus.java    |  14 -
 common/pom.xml                                  |  19 +
 .../common/rest/api/beans/AbstractQuery.java    |  67 +++
 .../common/rest/api/beans/AnyListQuery.java     |   2 +-
 .../syncope/common/rest/api/beans/AnyQuery.java |  40 ++
 .../common/rest/api/beans/ListQuery.java        |  98 ----
 .../common/rest/api/beans/TaskQuery.java        |  64 +++
 .../common/rest/api/service/JAXRSService.java   |   6 +
 .../common/rest/api/service/ReportService.java  |   8 +-
 .../common/rest/api/service/TaskService.java    |  22 +-
 .../apache/syncope/core/logic/ReportLogic.java  |  10 +-
 .../syncope/core/logic/ResourceLogic.java       |   8 +-
 .../apache/syncope/core/logic/SyncopeLogic.java |  25 +-
 .../apache/syncope/core/logic/TaskLogic.java    |  65 +--
 .../init/ClassPathScanImplementationLookup.java |   6 +
 .../syncope/core/misc/ConnObjectUtils.java      | 232 ++-------
 .../apache/syncope/core/misc/MappingUtils.java  | 501 +++++++++++++------
 .../core/misc/security/AuthDataAccessor.java    |   9 +-
 .../serialization/GuardedStringSerializer.java  |   4 +-
 .../persistence/api/ImplementationLookup.java   |   1 +
 .../core/persistence/api/dao/ReportDAO.java     |   5 -
 .../core/persistence/api/dao/TaskDAO.java       |   8 +-
 .../api/entity/resource/ExternalResource.java   |   5 -
 .../api/entity/resource/MappingItem.java        |   3 +
 .../api/entity/task/PropagationTask.java        |   9 +-
 .../core/persistence/jpa/dao/AbstractDAO.java   |  25 -
 .../core/persistence/jpa/dao/JPAReportDAO.java  |  27 +-
 .../core/persistence/jpa/dao/JPATaskDAO.java    | 140 ++++--
 .../persistence/jpa/dao/JPATaskExecDAO.java     |   9 +-
 .../entity/resource/JPAExternalResource.java    |  16 -
 .../jpa/entity/resource/JPAMappingItem.java     |  22 +
 .../jpa/entity/task/JPAPropagationTask.java     |  29 +-
 .../entity/ExternalResourceValidator.java       |  22 +
 .../entity/PropagationTaskValidator.java        |   3 +-
 .../core/persistence/jpa/inner/ReportTest.java  |   4 +-
 .../core/persistence/jpa/inner/TaskTest.java    |  19 +-
 .../persistence/jpa/outer/ResourceTest.java     |   5 +-
 .../core/persistence/jpa/outer/TaskTest.java    |  11 +-
 .../test/resources/domains/MasterContent.xml    | 109 ++--
 .../src/test/resources/domains/TwoContent.xml   |   6 +-
 core/pom.xml                                    |  19 +
 .../core/provisioning/api/Connector.java        |  19 +-
 .../api/data/MappingItemTransformer.java        |  47 ++
 .../provisioning/java/AsyncConnectorFacade.java |  14 +-
 .../provisioning/java/ConnectorFacadeProxy.java |  55 +-
 .../provisioning/java/VirAttrHandlerImpl.java   |  44 +-
 .../java/data/AbstractAnyDataBinder.java        |  19 +-
 .../data/DefaultMappingItemTransformer.java     |  40 ++
 .../java/data/ResourceDataBinderImpl.java       |   4 -
 .../AbstractPropagationTaskExecutor.java        |  64 ++-
 .../propagation/DefaultPropagationActions.java  |   2 +-
 .../propagation/DefaultPropagationReporter.java |   2 +-
 .../LDAPPasswordPropagationActions.java         |   2 +-
 .../PriorityPropagationTaskExecutor.java        |   2 +-
 .../propagation/PropagationManagerImpl.java     |  13 +-
 .../java/sync/AbstractPushResultHandler.java    |   6 +-
 .../java/sync/AbstractSyncResultHandler.java    |   2 +-
 .../sync/PlainAttrsSyncCorrelationRule.java     |  41 +-
 .../core/provisioning/java/sync/SyncUtils.java  |  37 +-
 .../java/ResourceDataBinderTest.java            |   2 -
 .../rest/cxf/service/ReportServiceImpl.java     |  13 +-
 .../core/rest/cxf/service/TaskServiceImpl.java  |  34 +-
 deb/pom.xml                                     |  27 +-
 ext/pom.xml                                     |  19 +
 .../reference/PrefixMappingItemTransformer.java |  55 ++
 .../fit/core/reference/AbstractTaskITCase.java  |   2 +-
 .../fit/core/reference/ConnectorITCase.java     |  10 +-
 .../fit/core/reference/MultitenancyITCase.java  |   3 +-
 .../core/reference/PropagationTaskITCase.java   |  44 +-
 .../fit/core/reference/PushTaskITCase.java      |   4 +-
 .../fit/core/reference/ReportITCase.java        |   8 +-
 .../fit/core/reference/SchedTaskITCase.java     |   2 +-
 .../fit/core/reference/SyncTaskITCase.java      | 127 +++--
 .../syncope/fit/core/reference/UserITCase.java  |  57 +--
 .../fit/core/reference/VirAttrITCase.java       |  12 +-
 fit/pom.xml                                     |  19 +
 installer/pom.xml                               |  17 +
 pom.xml                                         |  97 +++-
 .../getting-started/getting-started.adoc        |  64 +++
 .../reference-guide/reference-guide.adoc        | 100 ++++
 standalone/pom.xml                              |  17 +
 146 files changed, 3112 insertions(+), 2459 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractConnectorConfPanel.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractConnectorConfPanel.java
index 0000000,0000000..c055c95
new file mode 100644
--- /dev/null
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractConnectorConfPanel.java
@@@ -1,0 -1,0 +1,114 @@@
++/*
++ * 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.panels;
++
++import java.util.ArrayList;
++import java.util.Collections;
++import java.util.Comparator;
++import java.util.List;
++import java.util.Set;
++import 
org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
++import org.apache.syncope.common.lib.AbstractBaseBean;
++import org.apache.syncope.common.lib.types.ConnConfProperty;
++import org.apache.wicket.ajax.AjaxRequestTarget;
++import org.apache.wicket.ajax.markup.html.form.AjaxButton;
++import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
++import org.apache.wicket.markup.html.WebMarkupContainer;
++import org.apache.wicket.markup.html.form.Form;
++import org.apache.wicket.markup.html.panel.Panel;
++import org.apache.wicket.model.IModel;
++import org.apache.wicket.model.PropertyModel;
++import org.apache.wicket.model.ResourceModel;
++
++/**
++ * Modal window with Connector form.
++ *
++ * @param <T> model type.
++ */
++public abstract class AbstractConnectorConfPanel<T extends AbstractBaseBean> 
extends Panel {
++
++    private static final long serialVersionUID = -2025535531121434050L;
++
++    protected final WebMarkupContainer propertiesContainer;
++
++    protected final AjaxButton check;
++
++    protected final IModel<T> model;
++
++    public AbstractConnectorConfPanel(final String id, final IModel<T> model) 
{
++
++        super(id, model);
++        this.model = model;
++        setOutputMarkupId(true);
++
++        propertiesContainer = new 
WebMarkupContainer("connectorPropertiesContainer");
++        propertiesContainer.setOutputMarkupId(true);
++        add(propertiesContainer);
++
++        check = new IndicatingAjaxButton("check", new ResourceModel("check")) 
{
++
++            private static final long serialVersionUID = 
-7978723352517770644L;
++
++            @Override
++            public void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
++                check(target);
++            }
++        };
++        propertiesContainer.add(check);
++    }
++
++    protected void setConfPropertyListView(final String modelExpression, 
final boolean withOverridable) {
++
++        final ConnConfPropertyListView connPropView = new 
ConnConfPropertyListView(
++                "connectorProperties",
++                new PropertyModel<List<ConnConfProperty>>(model.getObject(), 
modelExpression) {
++
++                    private static final long serialVersionUID = 1L;
++
++                    @Override
++                    public List<ConnConfProperty> getObject() {
++                        final List<ConnConfProperty> res = new 
ArrayList<>((Set<ConnConfProperty>) super.getObject());
++
++                        // re-order properties
++                        Collections.sort(res, new 
Comparator<ConnConfProperty>() {
++
++                            @Override
++                            public int compare(final ConnConfProperty left, 
final ConnConfProperty right) {
++                                if (left == null) {
++                                    return -1;
++                                } else {
++                                    return left.compareTo(right);
++                                }
++                            }
++                        });
++
++                        return res;
++                    }
++                },
++                withOverridable
++        );
++
++        connPropView.setOutputMarkupId(true);
++        propertiesContainer.add(connPropView);
++    }
++
++    protected abstract void check(final AjaxRequestTarget taget);
++
++    protected abstract List<ConnConfProperty> getConnProperties(final T 
instance);
++}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
index fa18012,1ed9050..15f4f02
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractResourceModal.java
@@@ -19,11 -19,10 +19,17 @@@
  package org.apache.syncope.client.console.panels;
  
  import java.io.Serializable;
++import java.util.ArrayList;
++import java.util.List;
  import org.apache.syncope.client.console.topology.TopologyNode;
 +import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 +import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal.ModalEvent;
  import org.apache.wicket.PageReference;
  import org.apache.wicket.ajax.AjaxRequestTarget;
 -import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
++import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
++import org.apache.wicket.extensions.markup.html.tabs.ITab;
++import org.apache.wicket.markup.html.WebMarkupContainer;
++import org.apache.wicket.markup.html.form.Form;
  
  /**
   * Modal window with Resource form.
@@@ -32,8 -31,8 +38,46 @@@ public abstract class AbstractResourceM
  
      private static final long serialVersionUID = 1734415311027284221L;
  
 -    public AbstractResourceModal(final ModalWindow window, final 
PageReference pageRef) {
 -        super(window, pageRef);
++    protected final List<ITab> tabs;
++
 +    public AbstractResourceModal(final BaseModal<?> modal, final 
PageReference pageRef) {
 +        super(modal, pageRef);
++
++        this.tabs = new ArrayList<>();
++        add(new AjaxBootstrapTabbedPanel<ITab>("tabbedPanel", tabs));
++    }
++
++    private class AjaxBootstrapTabbedPanel<T extends ITab>
++            extends 
de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel<T>
 {
++
++        private static final long serialVersionUID = 1L;
++
++        public AjaxBootstrapTabbedPanel(final String id, final List<T> tabs) {
++            super(id, tabs);
++        }
++
++        @Override
++        protected WebMarkupContainer newLink(final String linkId, final int 
index) {
++            return new AjaxSubmitLink(linkId) {
++
++                private static final long serialVersionUID = 1L;
++
++                @Override
++                protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
++                    setSelectedTab(index);
++                    if (target != null) {
++                        target.add(AjaxBootstrapTabbedPanel.this);
++                    }
++                    onAjaxUpdate(target);
++                }
++
++                @Override
++                protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
++                    modal.getFeedbackPanel().refresh(target);
++                }
++            };
++        }
++
      }
  
      public static class CreateEvent extends ModalEvent {
@@@ -74,6 -73,6 +118,5 @@@
          public Serializable getParent() {
              return parent;
          }
--
      }
  }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorCapabilitiesPanel.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorCapabilitiesPanel.java
index 0000000,0000000..fbb8059
new file mode 100644
--- /dev/null
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorCapabilitiesPanel.java
@@@ -1,0 -1,0 +1,58 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements.  See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership.  The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License.  You may obtain a copy of the License at
++ *
++ *   http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied.  See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++package org.apache.syncope.client.console.panels;
++
++import java.util.Arrays;
++import java.util.List;
++import 
org.apache.syncope.client.console.wicket.markup.html.form.CheckBoxMultipleChoiceFieldPanel;
++import org.apache.syncope.common.lib.to.ConnInstanceTO;
++import org.apache.syncope.common.lib.types.ConnectorCapability;
++import org.apache.wicket.markup.html.panel.Panel;
++import org.apache.wicket.model.IModel;
++import org.apache.wicket.model.LoadableDetachableModel;
++import org.apache.wicket.model.PropertyModel;
++
++/**
++ * Modal window with Connector form.
++ */
++public class ConnectorCapabilitiesPanel extends Panel {
++
++    private static final long serialVersionUID = -2025535531121434050L;
++
++    public ConnectorCapabilitiesPanel(final String id, final 
IModel<ConnInstanceTO> model) {
++
++        super(id, model);
++        setOutputMarkupId(true);
++
++        final IModel<List<ConnectorCapability>> all = new 
LoadableDetachableModel<List<ConnectorCapability>>() {
++
++            private static final long serialVersionUID = 5275935387613157437L;
++
++            @Override
++            protected List<ConnectorCapability> load() {
++                return Arrays.asList(ConnectorCapability.values());
++            }
++        };
++
++        add(new CheckBoxMultipleChoiceFieldPanel<>(
++                "capabilitiesPalette",
++                new 
PropertyModel<List<ConnectorCapability>>(model.getObject(), "capabilities"),
++                all));
++    }
++}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java
index 0000000,0000000..2e813ed
new file mode 100644
--- /dev/null
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorConfPanel.java
@@@ -1,0 -1,0 +1,86 @@@
++/*
++ * 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.panels;
++
++import java.util.ArrayList;
++import java.util.List;
++import org.apache.commons.collections4.CollectionUtils;
++import org.apache.commons.collections4.Transformer;
++import org.apache.syncope.common.lib.to.ConnBundleTO;
++import org.apache.syncope.common.lib.to.ConnInstanceTO;
++import org.apache.syncope.common.lib.types.ConnConfPropSchema;
++import org.apache.syncope.common.lib.types.ConnConfProperty;
++import org.apache.wicket.model.IModel;
++
++/**
++ * Modal window with Connector form.
++ */
++public abstract class ConnectorConfPanel extends 
AbstractConnectorConfPanel<ConnInstanceTO> {
++
++    private static final long serialVersionUID = -2025535531121434050L;
++
++    private final List<ConnBundleTO> bundles;
++
++    public ConnectorConfPanel(final String id, final IModel<ConnInstanceTO> 
model, final List<ConnBundleTO> bundles) {
++
++        super(id, model);
++        this.bundles = bundles;
++
++        final List<ConnConfProperty> properties = 
getConnProperties(model.getObject());
++        model.getObject().getConfiguration().clear();
++        model.getObject().getConfiguration().addAll(properties);
++
++        setConfPropertyListView("configuration", true);
++    }
++
++    /**
++     * Ge available configuration properties.
++     *
++     * @param instance connector instance.
++     * @return configuration properties.
++     */
++    @Override
++    protected final List<ConnConfProperty> getConnProperties(final 
ConnInstanceTO instance) {
++
++        final List<ConnConfProperty> res = CollectionUtils.collect(
++                ConnectorModal.getBundle(instance, bundles).getProperties(),
++                new Transformer<ConnConfPropSchema, ConnConfProperty>() {
++
++                    @Override
++                    public ConnConfProperty transform(final 
ConnConfPropSchema key) {
++                        final ConnConfProperty property = new 
ConnConfProperty();
++                        property.setSchema(key);
++
++                        if (instance.getKey() != 0 && 
instance.getConfigurationMap().containsKey(key.getName())
++                        && 
instance.getConfigurationMap().get(key.getName()).getValues() != null) {
++                            
property.getValues().addAll(instance.getConfigurationMap().get(key.getName()).getValues());
++                            
property.setOverridable(instance.getConfigurationMap().get(key.getName()).isOverridable());
++                        }
++
++                        if (property.getValues().isEmpty() && 
!key.getDefaultValues().isEmpty()) {
++                            
property.getValues().addAll(key.getDefaultValues());
++                        }
++                        return property;
++                    }
++                },
++                new ArrayList<ConnConfProperty>());
++
++        return res;
++    }
++}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java
index 0000000,0000000..f7544c3
new file mode 100644
--- /dev/null
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorDetailsPanel.java
@@@ -1,0 -1,0 +1,197 @@@
++/*
++ * 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.panels;
++
++import java.util.ArrayList;
++import java.util.HashSet;
++import java.util.List;
++import org.apache.commons.collections4.CollectionUtils;
++import org.apache.commons.collections4.Predicate;
++import org.apache.commons.collections4.Transformer;
++import org.apache.syncope.client.console.commons.Constants;
++import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
++import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
++import 
org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
++import org.apache.syncope.common.lib.to.ConnBundleTO;
++import org.apache.syncope.common.lib.to.ConnInstanceTO;
++import org.apache.syncope.common.lib.to.ConnPoolConfTO;
++import org.apache.wicket.ajax.AjaxRequestTarget;
++import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
++import org.apache.wicket.markup.html.form.DropDownChoice;
++import org.apache.wicket.markup.html.panel.Panel;
++import org.apache.wicket.model.IModel;
++import org.apache.wicket.model.PropertyModel;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
++/**
++ * Modal window with Connector form.
++ */
++public class ConnectorDetailsPanel extends Panel {
++
++    private static final long serialVersionUID = -2025535531121434050L;
++
++    /**
++     * Logger.
++     */
++    private static final Logger LOG = 
LoggerFactory.getLogger(ConnectorDetailsPanel.class);
++
++    public ConnectorDetailsPanel(
++            final String id, final IModel<ConnInstanceTO> model, final 
List<ConnBundleTO> bundles) {
++
++        super(id, model);
++        setOutputMarkupId(true);
++
++        final AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
++                "displayName", "displayName", new 
PropertyModel<String>(model.getObject(), "displayName"), false);
++        displayName.setOutputMarkupId(true);
++        displayName.addRequiredLabel();
++        add(displayName);
++
++        final AjaxTextFieldPanel location = new AjaxTextFieldPanel(
++                "location",
++                "location",
++                new PropertyModel<String>(model.getObject(), "location"),
++                false);
++        location.setRequired(true);
++        location.addRequiredLabel();
++        location.setOutputMarkupId(true);
++        location.setEnabled(false);
++        add(location);
++
++        final AjaxDropDownChoicePanel<String> bundleName = new 
AjaxDropDownChoicePanel<>(
++                "connectorName",
++                "connectorName",
++                new PropertyModel<String>(model.getObject(), "bundleName"), 
false);
++
++        ((DropDownChoice<String>) bundleName.getField()).setNullValid(true);
++        bundleName.setChoices(CollectionUtils.collect(bundles, new 
Transformer<ConnBundleTO, String>() {
++
++            @Override
++            public String transform(final ConnBundleTO input) {
++                return input.getBundleName();
++            }
++        }, new ArrayList<String>()));
++
++        bundleName.setRequired(true);
++        bundleName.addRequiredLabel();
++        bundleName.setOutputMarkupId(true);
++        bundleName.setEnabled(model.getObject().getKey() == 0);
++        bundleName.getField().setOutputMarkupId(true);
++        add(bundleName);
++
++        final AjaxDropDownChoicePanel<String> version = new 
AjaxDropDownChoicePanel<>(
++                "version",
++                "version",
++                new PropertyModel<String>(model.getObject(), "version"), 
false);
++
++        version.setChoices(getVersions(model.getObject(), bundles));
++
++        version.setRequired(true);
++        version.addRequiredLabel();
++        version.setEnabled(model.getObject().getBundleName() != null);
++        version.setOutputMarkupId(true);
++        version.addRequiredLabel();
++        version.getField().setOutputMarkupId(true);
++        add(version);
++
++        bundleName.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
++
++            private static final long serialVersionUID = 
-1107858522700306810L;
++
++            @Override
++            protected void onUpdate(final AjaxRequestTarget target) {
++                ((DropDownChoice<String>) 
bundleName.getField()).setNullValid(false);
++                version.setChoices(getVersions(model.getObject(), bundles));
++                version.setEnabled(true);
++                target.add(version);
++            }
++        });
++
++        if (model.getObject().getPoolConf() == null) {
++            model.getObject().setPoolConf(new ConnPoolConfTO());
++        }
++
++        add(new SpinnerFieldPanel<>(
++                "connRequestTimeout",
++                "connRequestTimeout",
++                Integer.class,
++                new PropertyModel<Integer>(model, "connRequestTimeout"),
++                0,
++                Integer.MAX_VALUE));
++
++        add(new SpinnerFieldPanel<>(
++                "poolMaxObjects",
++                "poolMaxObjects",
++                Integer.class,
++                new PropertyModel<Integer>(model.getObject().getPoolConf(), 
"maxObjects"),
++                0,
++                Integer.MAX_VALUE));
++
++        add(new SpinnerFieldPanel<>(
++                "poolMinIdle",
++                "poolMinIdle",
++                Integer.class,
++                new PropertyModel<Integer>(model.getObject().getPoolConf(), 
"minIdle"),
++                0,
++                Integer.MAX_VALUE));
++
++        add(new SpinnerFieldPanel<>(
++                "poolMaxIdle",
++                "poolMaxIdle",
++                Integer.class,
++                new PropertyModel<Integer>(model.getObject().getPoolConf(), 
"maxIdle"),
++                0,
++                Integer.MAX_VALUE));
++
++        add(new SpinnerFieldPanel<>(
++                "poolMaxWait",
++                "poolMaxWait",
++                Long.class,
++                new PropertyModel<Long>(model.getObject().getPoolConf(), 
"maxWait"),
++                0L,
++                Long.MAX_VALUE));
++
++        add(new SpinnerFieldPanel<>(
++                "poolMinEvictableIdleTime",
++                "poolMinEvictableIdleTime",
++                Long.class,
++                new PropertyModel<Long>(model.getObject().getPoolConf(), 
"minEvictableIdleTimeMillis"),
++                0L,
++                Long.MAX_VALUE));
++    }
++
++    private List<String> getVersions(final ConnInstanceTO connInstanceTO, 
final List<ConnBundleTO> bundles) {
++        return new ArrayList<>(CollectionUtils.collect(
++                CollectionUtils.select(bundles, new Predicate<ConnBundleTO>() 
{
++
++                    @Override
++                    public boolean evaluate(final ConnBundleTO object) {
++                        return 
object.getLocation().equals(connInstanceTO.getLocation())
++                        && 
object.getBundleName().equals(connInstanceTO.getBundleName());
++                    }
++                }), new Transformer<ConnBundleTO, String>() {
++
++                    @Override
++                    public String transform(final ConnBundleTO input) {
++                        return input.getVersion();
++                    }
++                }, new HashSet<String>()));
++    }
++}

http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
index 8a1ecdb,4f5e8eb..6989135
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnectorModal.java
@@@ -18,51 -18,52 +18,28 @@@
   */
  package org.apache.syncope.client.console.panels;
  
++import static org.apache.syncope.client.console.panels.AbstractModalPanel.LOG;
++
 +import java.io.Serializable;
  import java.util.ArrayList;
--import java.util.Arrays;
--import java.util.Collections;
--import java.util.EnumSet;
--import java.util.HashMap;
  import java.util.List;
--import java.util.Map;
--import org.apache.commons.lang3.StringUtils;
++import org.apache.commons.collections4.CollectionUtils;
++import org.apache.commons.collections4.Predicate;
  import org.apache.syncope.client.console.commons.Constants;
--import org.apache.syncope.client.console.pages.BasePage;
++import org.apache.syncope.client.console.pages.AbstractBasePage;
  import org.apache.syncope.client.console.topology.Topology;
  import org.apache.syncope.client.console.topology.TopologyNode;
 -import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
 -import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 -import 
org.apache.syncope.client.console.wicket.markup.html.form.CheckBoxMultipleChoiceFieldPanel;
 -import 
org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
 -import 
org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
 -import org.apache.syncope.common.lib.SyncopeClientException;
 +import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
- import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
- import 
org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
- import 
org.apache.syncope.client.console.wicket.markup.html.form.CheckBoxMultipleChoiceFieldPanel;
- import 
org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
- import 
org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
- import org.apache.syncope.common.lib.SyncopeClientException;
  import org.apache.syncope.common.lib.to.ConnBundleTO;
  import org.apache.syncope.common.lib.to.ConnInstanceTO;
--import org.apache.syncope.common.lib.to.ConnPoolConfTO;
--import org.apache.syncope.common.lib.types.ConnConfPropSchema;
--import org.apache.syncope.common.lib.types.ConnConfProperty;
--import org.apache.syncope.common.lib.types.ConnectorCapability;
 -import org.apache.syncope.common.lib.types.Entitlement;
  import org.apache.wicket.PageReference;
  import org.apache.wicket.ajax.AjaxRequestTarget;
--import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
--import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
--import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 -import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
  import org.apache.wicket.event.Broadcast;
--import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
 -import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
--import org.apache.wicket.markup.html.WebMarkupContainer;
--import org.apache.wicket.markup.html.basic.Label;
--import org.apache.wicket.markup.html.form.DropDownChoice;
++import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
  import org.apache.wicket.markup.html.form.Form;
--import org.apache.wicket.markup.html.list.ListView;
--import org.apache.wicket.model.CompoundPropertyModel;
++import org.apache.wicket.markup.html.panel.Panel;
  import org.apache.wicket.model.IModel;
--import org.apache.wicket.model.LoadableDetachableModel;
--import org.apache.wicket.model.Model;
--import org.apache.wicket.model.PropertyModel;
  import org.apache.wicket.model.ResourceModel;
--import org.apache.wicket.validation.validator.RangeValidator;
  
  /**
   * Modal window with Connector form.
@@@ -71,391 -72,414 +48,140 @@@ public class ConnectorModal extends Abs
  
      private static final long serialVersionUID = -2025535531121434050L;
  
--    private final Map<String, Map<String, Map<String, ConnBundleTO>>> 
mapConnBundleTOs;
--
--    private final List<ConnectorCapability> selectedCapabilities;
--
--    private ConnBundleTO bundleTO;
--
--    private List<ConnConfProperty> properties;
--
--    private final WebMarkupContainer propertiesContainer;
- 
-     private final ListView<ConnConfProperty> connPropView;
- 
-     private final ConnInstanceTO connInstanceTO;
++    private final List<ConnBundleTO> bundles;
  
      public ConnectorModal(
-             final BaseModal<Serializable> modal, final PageReference pageRef, 
final ConnInstanceTO connInstanceTO) {
 -            final ModalWindow window, final PageReference pageRef, final 
ConnInstanceTO connInstanceTO) {
 -
 -        super(window, pageRef);
 -
 -        this.add(new Label("new", connInstanceTO.getKey() == 0
 -                ? new ResourceModel("new")
 -                : new Model<>(StringUtils.EMPTY)));
 -        this.add(new Label("key", connInstanceTO.getKey() == 0
 -                ? StringUtils.EMPTY
 -                : connInstanceTO.getKey()));
 -
 -        // general data setup
 -        selectedCapabilities = new ArrayList<>(connInstanceTO.getKey() == 0
 -                ? EnumSet.noneOf(ConnectorCapability.class)
 -                : connInstanceTO.getCapabilities());
 -
 -        mapConnBundleTOs = new HashMap<>();
 -        for (ConnBundleTO connBundleTO : connectorRestClient.getAllBundles()) 
{
 -            // by location
 -            if (!mapConnBundleTOs.containsKey(connBundleTO.getLocation())) {
 -                mapConnBundleTOs.put(connBundleTO.getLocation(), new 
HashMap<String, Map<String, ConnBundleTO>>());
 -            }
 -            final Map<String, Map<String, ConnBundleTO>> byLocation = 
mapConnBundleTOs.get(connBundleTO.getLocation());
 -
 -            // by name
 -            if (!byLocation.containsKey(connBundleTO.getBundleName())) {
 -                byLocation.put(connBundleTO.getBundleName(), new 
HashMap<String, ConnBundleTO>());
 -            }
 -            final Map<String, ConnBundleTO> byName = 
byLocation.get(connBundleTO.getBundleName());
 -
 -            // by version
 -            if (!byName.containsKey(connBundleTO.getVersion())) {
 -                byName.put(connBundleTO.getVersion(), connBundleTO);
 -            }
 -        }
 -
 -        bundleTO = getSelectedBundleTO(connInstanceTO);
 -        properties = fillProperties(bundleTO, connInstanceTO);
 -
 -        // form - first tab
 -        final Form<ConnInstanceTO> connectorForm = new Form<>(FORM);
 -        connectorForm.setModel(new CompoundPropertyModel<>(connInstanceTO));
 -        connectorForm.setOutputMarkupId(true);
 -        add(connectorForm);
 -
 -        propertiesContainer = new WebMarkupContainer("container");
 -        propertiesContainer.setOutputMarkupId(true);
 -        connectorForm.add(propertiesContainer);
 -
 -        final Form<ConnInstanceTO> connectorPropForm = new 
Form<>("connectorPropForm");
 -        connectorPropForm.setModel(new 
CompoundPropertyModel<>(connInstanceTO));
 -        connectorPropForm.setOutputMarkupId(true);
 -        propertiesContainer.add(connectorPropForm);
 -
 -        final AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
 -                "displayName", "display name", new 
PropertyModel<String>(connInstanceTO, "displayName"));
 -        displayName.setOutputMarkupId(true);
 -        displayName.addRequiredLabel();
 -        connectorForm.add(displayName);
++            final BaseModal<Serializable> modal,
++            final PageReference pageRef,
++            final IModel<ConnInstanceTO> model) {
  
 -        final AjaxDropDownChoicePanel<String> location = new 
AjaxDropDownChoicePanel<>("location", "location",
 -                new Model<>(bundleTO == null ? connInstanceTO.getLocation() : 
bundleTO.getLocation()));
 -        ((DropDownChoice<String>) location.getField()).setNullValid(true);
 -        location.setStyleSheet("long_dynamicsize");
 -        location.setChoices(new ArrayList<>(mapConnBundleTOs.keySet()));
 -        location.setRequired(true);
 -        location.addRequiredLabel();
 -        location.setOutputMarkupId(true);
 -        location.setEnabled(connInstanceTO.getKey() == 0 && 
StringUtils.isBlank(connInstanceTO.getLocation()));
 -        location.getField().setOutputMarkupId(true);
 -        connectorForm.add(location);
 +        super(modal, pageRef);
  
-         this.connInstanceTO = connInstanceTO;
- 
-         this.add(new Label("new", connInstanceTO.getKey() == 0
-                 ? new ResourceModel("new")
-                 : new Model<>(StringUtils.EMPTY)));
-         this.add(new Label("key", connInstanceTO.getKey() == 0
-                 ? StringUtils.EMPTY
-                 : connInstanceTO.getKey()));
- 
-         // general data setup
-         selectedCapabilities = new ArrayList<>(connInstanceTO.getKey() == 0
-                 ? EnumSet.noneOf(ConnectorCapability.class)
-                 : connInstanceTO.getCapabilities());
- 
-         mapConnBundleTOs = new HashMap<>();
-         for (ConnBundleTO connBundleTO : connectorRestClient.getAllBundles()) 
{
-             // by location
-             if (!mapConnBundleTOs.containsKey(connBundleTO.getLocation())) {
-                 mapConnBundleTOs.put(connBundleTO.getLocation(), new 
HashMap<String, Map<String, ConnBundleTO>>());
-             }
-             final Map<String, Map<String, ConnBundleTO>> byLocation = 
mapConnBundleTOs.get(connBundleTO.getLocation());
- 
-             // by name
-             if (!byLocation.containsKey(connBundleTO.getBundleName())) {
-                 byLocation.put(connBundleTO.getBundleName(), new 
HashMap<String, ConnBundleTO>());
-             }
-             final Map<String, ConnBundleTO> byName = 
byLocation.get(connBundleTO.getBundleName());
- 
-             // by version
-             if (!byName.containsKey(connBundleTO.getVersion())) {
-                 byName.put(connBundleTO.getVersion(), connBundleTO);
-             }
-         }
- 
-         bundleTO = getSelectedBundleTO(connInstanceTO);
-         properties = fillProperties(bundleTO, connInstanceTO);
- 
-         propertiesContainer = new WebMarkupContainer("container");
-         propertiesContainer.setOutputMarkupId(true);
-         add(propertiesContainer);
- 
-         final Form<ConnInstanceTO> connectorPropForm = new 
Form<>("connectorPropForm");
-         connectorPropForm.setModel(new 
CompoundPropertyModel<>(connInstanceTO));
-         connectorPropForm.setOutputMarkupId(true);
-         propertiesContainer.add(connectorPropForm);
- 
-         final AjaxTextFieldPanel displayName = new AjaxTextFieldPanel(
-                 "displayName", "display name", new 
PropertyModel<String>(connInstanceTO, "displayName"));
-         displayName.setOutputMarkupId(true);
-         displayName.addRequiredLabel();
-         add(displayName);
- 
-         final AjaxDropDownChoicePanel<String> location = new 
AjaxDropDownChoicePanel<>("location", "location",
-                 new Model<>(bundleTO == null ? connInstanceTO.getLocation() : 
bundleTO.getLocation()));
-         ((DropDownChoice<String>) location.getField()).setNullValid(true);
-         location.setStyleSheet("long_dynamicsize");
-         location.setChoices(new ArrayList<>(mapConnBundleTOs.keySet()));
-         location.setRequired(true);
-         location.addRequiredLabel();
-         location.setOutputMarkupId(true);
-         location.setEnabled(connInstanceTO.getKey() == 0 && 
StringUtils.isBlank(connInstanceTO.getLocation()));
-         location.getField().setOutputMarkupId(true);
-         add(location);
 -        final AjaxDropDownChoicePanel<String> connectorName = new 
AjaxDropDownChoicePanel<>("connectorName",
 -                "connectorName",
 -                new Model<>(bundleTO == null ? null : 
bundleTO.getBundleName()));
 -        ((DropDownChoice<String>) 
connectorName.getField()).setNullValid(true);
 -        connectorName.setStyleSheet("long_dynamicsize");
 -        connectorName.setChoices(bundleTO == null
 -                ? StringUtils.isBlank(connInstanceTO.getLocation())
 -                        ? new ArrayList<String>()
 -                        : new 
ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet())
 -                : new 
ArrayList<>(mapConnBundleTOs.get(bundleTO.getLocation()).keySet()));
 -        connectorName.setRequired(true);
 -        connectorName.addRequiredLabel();
 -        connectorName.setOutputMarkupId(true);
 -        connectorName.setEnabled(connInstanceTO.getKey() == 0);
 -        connectorName.getField().setOutputMarkupId(true);
 -        connectorForm.add(connectorName);
++        this.bundles = 
CollectionUtils.select(connectorRestClient.getAllBundles(),
++                new Predicate<ConnBundleTO>() {
  
-         final AjaxDropDownChoicePanel<String> connectorName = new 
AjaxDropDownChoicePanel<>("connectorName",
-                 "connectorName",
-                 new Model<>(bundleTO == null ? null : 
bundleTO.getBundleName()));
-         ((DropDownChoice<String>) 
connectorName.getField()).setNullValid(true);
-         connectorName.setStyleSheet("long_dynamicsize");
-         connectorName.setChoices(bundleTO == null
-                 ? StringUtils.isBlank(connInstanceTO.getLocation())
-                         ? new ArrayList<String>()
-                         : new 
ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet())
-                 : new 
ArrayList<>(mapConnBundleTOs.get(bundleTO.getLocation()).keySet()));
-         connectorName.setRequired(true);
-         connectorName.addRequiredLabel();
-         connectorName.setOutputMarkupId(true);
-         connectorName.setEnabled(connInstanceTO.getKey() == 0);
-         connectorName.getField().setOutputMarkupId(true);
-         add(connectorName);
- 
--        final AjaxDropDownChoicePanel<String> version = new 
AjaxDropDownChoicePanel<>("version", "version",
--                new Model<>(bundleTO == null ? null : bundleTO.getVersion()));
--        version.setStyleSheet("long_dynamicsize");
--        version.setChoices(bundleTO == null
--                ? new ArrayList<String>()
--                : new 
ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).
--                        get(connInstanceTO.getBundleName()).keySet()));
--        version.setRequired(true);
--        version.addRequiredLabel();
--        version.setEnabled(connInstanceTO.getBundleName() != null);
--        version.setOutputMarkupId(true);
--        version.addRequiredLabel();
--        version.getField().setOutputMarkupId(true);
-         add(version);
 -        connectorForm.add(version);
--
--        final SpinnerFieldPanel<Integer> connRequestTimeout = new 
SpinnerFieldPanel<>("connRequestTimeout",
--                "connRequestTimeout", Integer.class,
--                new PropertyModel<Integer>(connInstanceTO, 
"connRequestTimeout"), 0, null);
--        connRequestTimeout.getField().add(new RangeValidator<>(0, 
Integer.MAX_VALUE));
-         add(connRequestTimeout);
 -        connectorForm.add(connRequestTimeout);
--
--        if (connInstanceTO.getPoolConf() == null) {
--            connInstanceTO.setPoolConf(new ConnPoolConfTO());
--        }
--        final SpinnerFieldPanel<Integer> poolMaxObjects = new 
SpinnerFieldPanel<>("poolMaxObjects", "poolMaxObjects",
--                Integer.class,
--                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), 
"maxObjects"), 0, null);
--        poolMaxObjects.getField().add(new RangeValidator<>(0, 
Integer.MAX_VALUE));
-         add(poolMaxObjects);
 -        connectorForm.add(poolMaxObjects);
--        final SpinnerFieldPanel<Integer> poolMinIdle = new 
SpinnerFieldPanel<>("poolMinIdle", "poolMinIdle",
--                Integer.class,
--                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), 
"minIdle"), 0, null);
--        poolMinIdle.getField().add(new RangeValidator<>(0, 
Integer.MAX_VALUE));
-         add(poolMinIdle);
 -        connectorForm.add(poolMinIdle);
--        final SpinnerFieldPanel<Integer> poolMaxIdle = new 
SpinnerFieldPanel<>("poolMaxIdle", "poolMaxIdle",
--                Integer.class,
--                new PropertyModel<Integer>(connInstanceTO.getPoolConf(), 
"maxIdle"), 0, null);
--        poolMaxIdle.getField().add(new RangeValidator<>(0, 
Integer.MAX_VALUE));
-         add(poolMaxIdle);
 -        connectorForm.add(poolMaxIdle);
--        final SpinnerFieldPanel<Long> poolMaxWait = new 
SpinnerFieldPanel<>("poolMaxWait", "poolMaxWait", Long.class,
--                new PropertyModel<Long>(connInstanceTO.getPoolConf(), 
"maxWait"), 0L, null);
--        poolMaxWait.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE));
-         add(poolMaxWait);
 -        connectorForm.add(poolMaxWait);
--        final SpinnerFieldPanel<Long> poolMinEvictableIdleTime = new 
SpinnerFieldPanel<>("poolMinEvictableIdleTime",
--                "poolMinEvictableIdleTime", Long.class,
--                new PropertyModel<Long>(connInstanceTO.getPoolConf(), 
"minEvictableIdleTimeMillis"),
--                0L, null);
--        poolMinEvictableIdleTime.getField().add(new RangeValidator<>(0L, 
Long.MAX_VALUE));
-         add(poolMinEvictableIdleTime);
 -        connectorForm.add(poolMinEvictableIdleTime);
 -
 -        // form - first tab - onchange()
 -        location.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 -
 -            private static final long serialVersionUID = 
-1107858522700306810L;
 -
 -            @Override
 -            protected void onUpdate(final AjaxRequestTarget target) {
 -                ((DropDownChoice<String>) 
location.getField()).setNullValid(false);
 -                connInstanceTO.setLocation(location.getModelObject());
 -                target.add(location);
 -
 -                connectorName.setChoices(new ArrayList<>(
 -                        
mapConnBundleTOs.get(location.getModelObject()).keySet()));
 -                connectorName.setEnabled(true);
 -                connectorName.getField().setModelValue(null);
 -                target.add(connectorName);
 -
 -                version.setChoices(new ArrayList<String>());
 -                version.getField().setModelValue(null);
 -                version.setEnabled(false);
 -                target.add(version);
 -
 -                properties.clear();
 -                target.add(propertiesContainer);
 -            }
 -        });
 -        connectorName.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 -
 -            private static final long serialVersionUID = 
-1107858522700306810L;
 -
 -            @Override
 -            protected void onUpdate(final AjaxRequestTarget target) {
 -                ((DropDownChoice<String>) 
connectorName.getField()).setNullValid(false);
 -                connInstanceTO.setBundleName(connectorName.getModelObject());
 -                target.add(connectorName);
++                    @Override
++                    public boolean evaluate(final ConnBundleTO object) {
++                        return 
object.getLocation().equals(model.getObject().getLocation());
++                    }
++                }, new ArrayList<ConnBundleTO>());
  
-         // form - first tab - onchange()
-         location.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 -                List<String> versions = new ArrayList<>(
 -                        
mapConnBundleTOs.get(location.getModelObject()).get(connectorName.getModelObject()).keySet());
 -                version.setChoices(versions);
 -                version.setEnabled(true);
 -                if (versions.size() == 1) {
 -                    selectVersion(target, connInstanceTO, version, 
versions.get(0));
 -                    version.getField().setModelObject(versions.get(0));
 -                } else {
 -                    version.getField().setModelValue(null);
 -                    properties.clear();
 -                    target.add(propertiesContainer);
 -                }
 -                target.add(version);
 -            }
 -        });
 -        version.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
++        //--------------------------------
++        // Connector details panel
++        //--------------------------------
++        tabs.add(new AbstractTab(new ResourceModel("general", "general")) {
  
--            private static final long serialVersionUID = 
-1107858522700306810L;
++            private static final long serialVersionUID = 
-5861786415855103549L;
  
              @Override
--            protected void onUpdate(final AjaxRequestTarget target) {
-                 ((DropDownChoice<String>) 
location.getField()).setNullValid(false);
-                 connInstanceTO.setLocation(location.getModelObject());
-                 target.add(location);
- 
-                 connectorName.setChoices(new ArrayList<>(
-                         
mapConnBundleTOs.get(location.getModelObject()).keySet()));
-                 connectorName.setEnabled(true);
-                 connectorName.getField().setModelValue(null);
-                 target.add(connectorName);
- 
-                 version.setChoices(new ArrayList<String>());
-                 version.getField().setModelValue(null);
-                 version.setEnabled(false);
-                 target.add(version);
- 
-                 properties.clear();
-                 target.add(propertiesContainer);
 -                selectVersion(target, connInstanceTO, version, 
version.getModelObject());
++            public Panel getPanel(final String panelId) {
++                return new ConnectorDetailsPanel(panelId, model, bundles);
              }
          });
-         connectorName.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
- 
-             private static final long serialVersionUID = 
-1107858522700306810L;
++        //--------------------------------
  
-             @Override
-             protected void onUpdate(final AjaxRequestTarget target) {
-                 ((DropDownChoice<String>) 
connectorName.getField()).setNullValid(false);
-                 connInstanceTO.setBundleName(connectorName.getModelObject());
-                 target.add(connectorName);
 -        // form - second tab (properties)
 -        final ListView<ConnConfProperty> connPropView = new 
ConnConfPropertyListView("connectorProperties",
 -                new PropertyModel<List<ConnConfProperty>>(this, "properties"),
 -                true, connInstanceTO.getConfiguration());
 -        connPropView.setOutputMarkupId(true);
 -        connectorPropForm.add(connPropView);
 -
 -        final AjaxButton check = new IndicatingAjaxButton("check", new 
ResourceModel("check")) {
++        //--------------------------------
++        // Connector configuration panel
++        //--------------------------------
++        tabs.add(new AbstractTab(new ResourceModel("configuration", 
"configuration")) {
  
-                 List<String> versions = new ArrayList<>(
-                         
mapConnBundleTOs.get(location.getModelObject()).get(connectorName.getModelObject()).keySet());
-                 version.setChoices(versions);
-                 version.setEnabled(true);
-                 if (versions.size() == 1) {
-                     selectVersion(target, connInstanceTO, version, 
versions.get(0));
-                     version.getField().setModelObject(versions.get(0));
-                 } else {
-                     version.getField().setModelValue(null);
-                     properties.clear();
-                     target.add(propertiesContainer);
-                 }
-                 target.add(version);
-             }
-         });
-         version.getField().add(new 
AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
- 
-             private static final long serialVersionUID = 
-1107858522700306810L;
 -            private static final long serialVersionUID = 
-7978723352517770644L;
++            private static final long serialVersionUID = 
-5861786415855103549L;
  
              @Override
-             protected void onUpdate(final AjaxRequestTarget target) {
-                 selectVersion(target, connInstanceTO, version, 
version.getModelObject());
-             }
-         });
- 
-         // form - second tab (properties)
-         connPropView = new ConnConfPropertyListView("connectorProperties",
-                 new PropertyModel<List<ConnConfProperty>>(this, "properties"),
-                 true, connInstanceTO.getConfiguration());
-         connPropView.setOutputMarkupId(true);
-         connectorPropForm.add(connPropView);
- 
-         final AjaxButton check = new IndicatingAjaxButton("check", new 
ResourceModel("check")) {
 -            public void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
 -                final ConnInstanceTO conn = (ConnInstanceTO) 
form.getModelObject();
++            public Panel getPanel(final String panelId) {
++                return new ConnectorConfPanel(panelId, model, bundles) {
  
-             private static final long serialVersionUID = 
-7978723352517770644L;
- 
-             @Override
-             public void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
-                 final ConnInstanceTO conn = (ConnInstanceTO) 
form.getModelObject();
- 
--                // ensure that connector bundle information is in sync
--                conn.setBundleName(bundleTO.getBundleName());
--                conn.setVersion(bundleTO.getVersion());
--                conn.setConnectorName(bundleTO.getConnectorName());
--
--                if (connectorRestClient.check(conn)) {
--                    info(getString("success_connection"));
--                } else {
--                    error(getString("error_connection"));
--                }
--
-                 modal.getFeedbackPanel().refresh(target);
 -                feedbackPanel.refresh(target);
--            }
--        };
--        connectorPropForm.add(check);
--
--        // form - third tab (capabilities)
-         final IModel<List<ConnectorCapability>> capabilities
-                 = new LoadableDetachableModel<List<ConnectorCapability>>() {
 -        final IModel<List<ConnectorCapability>> capabilities =
 -                 new LoadableDetachableModel<List<ConnectorCapability>>() {
--
--                    private static final long serialVersionUID = 
5275935387613157437L;
++                    private static final long serialVersionUID = 1L;
  
                      @Override
--                    protected List<ConnectorCapability> load() {
--                        return Arrays.asList(ConnectorCapability.values());
++                    protected void check(final AjaxRequestTarget target) {
++                        if (connectorRestClient.check(model.getObject())) {
++                            info(getString("success_connection"));
++                        } else {
++                            error(getString("error_connection"));
++                        }
++                        modal.getFeedbackPanel().refresh(target);
                      }
--                };
-         CheckBoxMultipleChoiceFieldPanel<ConnectorCapability> 
capabilitiesPalette
-                 = new CheckBoxMultipleChoiceFieldPanel<>(
 -        CheckBoxMultipleChoiceFieldPanel<ConnectorCapability> 
capabilitiesPalette =
 -                 new CheckBoxMultipleChoiceFieldPanel<>(
--                        "capabilitiesPalette",
--                        new PropertyModel<List<ConnectorCapability>>(this, 
"selectedCapabilities"), capabilities);
--
--        capabilitiesPalette.add(new AjaxFormChoiceComponentUpdatingBehavior() 
{
 -
 -            private static final long serialVersionUID = 
-1107858522700306810L;
  
-             private static final long serialVersionUID = 
-1107858522700306810L;
- 
--            @Override
--            protected void onUpdate(final AjaxRequestTarget target) {
++                };
              }
          });
++        //--------------------------------
  
-         add(capabilitiesPalette);
-     }
 -        connectorForm.add(capabilitiesPalette);
--
-     private ConnBundleTO getSelectedBundleTO(final ConnInstanceTO 
connInstanceTO) {
-         ConnBundleTO result = null;
-         if (connInstanceTO != null
-                 && StringUtils.isNotBlank(connInstanceTO.getLocation())
-                 && StringUtils.isNotBlank(connInstanceTO.getBundleName())
-                 && StringUtils.isNotBlank(connInstanceTO.getVersion())
-                 && 
mapConnBundleTOs.containsKey(connInstanceTO.getLocation())) {
 -        // form - submit / cancel buttons
 -        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new 
Model<>(getString(SUBMIT))) {
--
-             Map<String, Map<String, ConnBundleTO>> byLocation = 
mapConnBundleTOs.get(connInstanceTO.getLocation());
-             if (byLocation.containsKey(connInstanceTO.getBundleName())) {
-                 Map<String, ConnBundleTO> byName = 
byLocation.get(connInstanceTO.getBundleName());
-                 if (byName.containsKey(connInstanceTO.getVersion())) {
-                     result = byName.get(connInstanceTO.getVersion());
-                 }
-             }
-         }
-         return result;
-     }
 -            private static final long serialVersionUID = -958724007591692537L;
--
-     private List<ConnConfProperty> fillProperties(final ConnBundleTO 
bundleTO, final ConnInstanceTO connInstanceTO) {
-         final List<ConnConfProperty> props = new ArrayList<>();
 -            @Override
 -            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
 -                final ConnInstanceTO conn = (ConnInstanceTO) 
form.getModelObject();
--
-         if (bundleTO != null) {
-             for (ConnConfPropSchema key : bundleTO.getProperties()) {
-                 final ConnConfProperty property = new ConnConfProperty();
-                 property.setSchema(key);
-                 if (connInstanceTO.getKey() != 0
-                         && 
connInstanceTO.getConfigurationMap().containsKey(key.getName())
-                         && 
connInstanceTO.getConfigurationMap().get(key.getName()).getValues() != null) {
 -                conn.setConnectorName(bundleTO.getConnectorName());
 -                conn.setBundleName(bundleTO.getBundleName());
 -                conn.setVersion(bundleTO.getVersion());
 -                conn.getConfiguration().clear();
 -                conn.getConfiguration().addAll(connPropView.getModelObject());
--
-                     
property.getValues().addAll(connInstanceTO.getConfigurationMap().get(key.getName()).getValues());
-                     
property.setOverridable(connInstanceTO.getConfigurationMap().get(key.getName()).isOverridable());
 -                // Set the model object's capabilities to 
capabilitiesPalette's converted Set
 -                conn.getCapabilities().clear();
 -                conn.getCapabilities().addAll(selectedCapabilities.isEmpty()
 -                        ? EnumSet.noneOf(ConnectorCapability.class)
 -                        : EnumSet.copyOf(selectedCapabilities));
 -
 -                // Reset pool configuration if all fields are null
 -                if (conn.getPoolConf() != null
 -                        && conn.getPoolConf().getMaxIdle() == null
 -                        && conn.getPoolConf().getMaxObjects() == null
 -                        && conn.getPoolConf().getMaxWait() == null
 -                        && conn.getPoolConf().getMinEvictableIdleTimeMillis() 
== null
 -                        && conn.getPoolConf().getMinIdle() == null) {
 -
 -                    conn.setPoolConf(null);
--                }
 -
 -                try {
 -                    if (connInstanceTO.getKey() == 0) {
 -                        connectorRestClient.create(conn);
 -                        send(pageRef.getPage(), Broadcast.BREADTH, new 
CreateEvent(
 -                                conn.getKey(),
 -                                conn.getDisplayName(),
 -                                TopologyNode.Kind.CONNECTOR,
 -                                
conn.getLocation().startsWith(Topology.CONNECTOR_SERVER_LOCATION_PREFIX)
 -                                        ? conn.getLocation() : 
Topology.ROOT_NAME,
 -                                target));
 -                    } else {
 -                        connectorRestClient.update(conn);
 -                    }
++        //--------------------------------
++        // Connector configuration panel
++        //--------------------------------
++        tabs.add(new AbstractTab(new ResourceModel("capabilities", 
"capabilities")) {
  
-                 if (property.getValues().isEmpty() && 
!key.getDefaultValues().isEmpty()) {
-                     property.getValues().addAll(key.getDefaultValues());
 -                    ((BasePage) pageRef.getPage()).setModalResult(true);
 -                    window.close(target);
 -                } catch (SyncopeClientException e) {
 -                    error(getString(Constants.ERROR) + ": " + e.getMessage());
 -                    feedbackPanel.refresh(target);
 -                    ((BasePage) pageRef.getPage()).setModalResult(false);
 -                    LOG.error("While creating or updating connector {}", 
conn, e);
--                }
 -            }
++            private static final long serialVersionUID = 
-5861786415855103549L;
  
-                 props.add(property);
+             @Override
 -            protected void onError(final AjaxRequestTarget target, final 
Form<?> form) {
 -                feedbackPanel.refresh(target);
++            public Panel getPanel(final String panelId) {
++                return new ConnectorCapabilitiesPanel(panelId, model);
              }
-         }
- 
-         // re-order properties (implements Comparable)
-         Collections.sort(props);
-         return props;
-     }
 -        };
 -        String entitlements = connInstanceTO.getKey() == 0
 -                ? Entitlement.CONNECTOR_CREATE : Entitlement.CONNECTOR_UPDATE;
--
-     private void selectVersion(final AjaxRequestTarget target, final 
ConnInstanceTO connInstanceTO,
-             final AjaxDropDownChoicePanel<String> version, final String 
versionValue) {
 -        MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, 
entitlements);
 -        connectorForm.add(submit);
--
-         connInstanceTO.setVersion(versionValue);
-         target.add(version);
 -        final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, 
new ResourceModel(CANCEL)) {
--
-         bundleTO = getSelectedBundleTO(connInstanceTO);
-         properties = fillProperties(bundleTO, connInstanceTO);
-         target.add(propertiesContainer);
 -            private static final long serialVersionUID = -958724007591692537L;
++        });
++        //--------------------------------
 +    }
  
-     public List<ConnConfProperty> getProperties() {
-         return properties;
 -            @Override
 -            protected void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
 -                window.close(target);
 -            }
 -        };
 -        cancel.setDefaultFormProcessing(false);
 -        connectorForm.add(cancel);
++    @Override
++    public void onError(final AjaxRequestTarget target, final Form<?> form) {
++        modal.getFeedbackPanel().refresh(target);
      }
  
 -    private ConnBundleTO getSelectedBundleTO(final ConnInstanceTO 
connInstanceTO) {
 -        ConnBundleTO result = null;
 -        if (connInstanceTO != null
 -                && StringUtils.isNotBlank(connInstanceTO.getLocation())
 -                && StringUtils.isNotBlank(connInstanceTO.getBundleName())
 -                && StringUtils.isNotBlank(connInstanceTO.getVersion())
 -                && 
mapConnBundleTOs.containsKey(connInstanceTO.getLocation())) {
 +    @Override
 +    public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
-         final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject();
++        final ConnInstanceTO connInstanceTO = (ConnInstanceTO) 
form.getModelObject();
  
-         conn.setConnectorName(bundleTO.getConnectorName());
-         conn.setBundleName(bundleTO.getBundleName());
-         conn.setVersion(bundleTO.getVersion());
-         conn.getConfiguration().clear();
-         conn.getConfiguration().addAll(connPropView.getModelObject());
 -            Map<String, Map<String, ConnBundleTO>> byLocation = 
mapConnBundleTOs.get(connInstanceTO.getLocation());
 -            if (byLocation.containsKey(connInstanceTO.getBundleName())) {
 -                Map<String, ConnBundleTO> byName = 
byLocation.get(connInstanceTO.getBundleName());
 -                if (byName.containsKey(connInstanceTO.getVersion())) {
 -                    result = byName.get(connInstanceTO.getVersion());
 -                }
 -            }
 -        }
 -        return result;
 -    }
++        final ConnBundleTO bundleTO = 
ConnectorModal.getBundle(connInstanceTO, bundles);
  
-         // Set the model object's capabilities to capabilitiesPalette's 
converted Set
-         conn.getCapabilities().clear();
-         conn.getCapabilities().addAll(selectedCapabilities.isEmpty()
-                 ? EnumSet.noneOf(ConnectorCapability.class)
-                 : EnumSet.copyOf(selectedCapabilities));
 -    private List<ConnConfProperty> fillProperties(final ConnBundleTO 
bundleTO, final ConnInstanceTO connInstanceTO) {
 -        final List<ConnConfProperty> props = new ArrayList<>();
++        connInstanceTO.setConnectorName(bundleTO.getConnectorName());
++        connInstanceTO.setBundleName(bundleTO.getBundleName());
++        connInstanceTO.setVersion(bundleTO.getVersion());
  
 -        if (bundleTO != null) {
 -            for (ConnConfPropSchema key : bundleTO.getProperties()) {
 -                final ConnConfProperty property = new ConnConfProperty();
 -                property.setSchema(key);
 -                if (connInstanceTO.getKey() != 0
 -                        && 
connInstanceTO.getConfigurationMap().containsKey(key.getName())
 -                        && 
connInstanceTO.getConfigurationMap().get(key.getName()).getValues() != null) {
 +        // Reset pool configuration if all fields are null
-         if (conn.getPoolConf() != null
-                 && conn.getPoolConf().getMaxIdle() == null
-                 && conn.getPoolConf().getMaxObjects() == null
-                 && conn.getPoolConf().getMaxWait() == null
-                 && conn.getPoolConf().getMinEvictableIdleTimeMillis() == null
-                 && conn.getPoolConf().getMinIdle() == null) {
- 
-             conn.setPoolConf(null);
++        if (connInstanceTO.getPoolConf() != null
++                && connInstanceTO.getPoolConf().getMaxIdle() == null
++                && connInstanceTO.getPoolConf().getMaxObjects() == null
++                && connInstanceTO.getPoolConf().getMaxWait() == null
++                && 
connInstanceTO.getPoolConf().getMinEvictableIdleTimeMillis() == null
++                && connInstanceTO.getPoolConf().getMinIdle() == null) {
+ 
 -                    
property.getValues().addAll(connInstanceTO.getConfigurationMap().get(key.getName()).getValues());
 -                    
property.setOverridable(connInstanceTO.getConfigurationMap().get(key.getName()).isOverridable());
 -                }
++            connInstanceTO.setPoolConf(null);
 +        }
  
 -                if (property.getValues().isEmpty() && 
!key.getDefaultValues().isEmpty()) {
 -                    property.getValues().addAll(key.getDefaultValues());
 -                }
 +        try {
 +            if (connInstanceTO.getKey() == 0) {
-                 connectorRestClient.create(conn);
++                connectorRestClient.create(connInstanceTO);
 +                send(pageRef.getPage(), Broadcast.BREADTH, new CreateEvent(
-                         conn.getKey(),
-                         conn.getDisplayName(),
++                        connInstanceTO.getKey(),
++                        connInstanceTO.getDisplayName(),
 +                        TopologyNode.Kind.CONNECTOR,
-                         
conn.getLocation().startsWith(Topology.CONNECTOR_SERVER_LOCATION_PREFIX)
-                                 ? conn.getLocation() : Topology.ROOT_NAME,
++                        
connInstanceTO.getLocation().startsWith(Topology.CONNECTOR_SERVER_LOCATION_PREFIX)
++                                ? connInstanceTO.getLocation() : 
Topology.ROOT_NAME,
 +                        target));
 +            } else {
-                 connectorRestClient.update(conn);
++                connectorRestClient.update(connInstanceTO);
 +            }
  
-             ((BasePage) pageRef.getPage()).setModalResult(true);
 -                props.add(property);
++            if (pageRef.getPage() instanceof AbstractBasePage) {
++                ((AbstractBasePage) pageRef.getPage()).setModalResult(true);
+             }
 +            modal.close(target);
-         } catch (SyncopeClientException e) {
++        } catch (Exception e) {
++            LOG.error("Failure managing resource {}", connInstanceTO, e);
 +            error(getString(Constants.ERROR) + ": " + e.getMessage());
 +            modal.getFeedbackPanel().refresh(target);
-             ((BasePage) pageRef.getPage()).setModalResult(false);
-             LOG.error("While creating or updating connector {}", conn, e);
          }
 -
 -        // re-order properties (implements Comparable)
 -        Collections.sort(props);
 -        return props;
      }
  
-     @Override
-     public void onError(final AjaxRequestTarget target, final Form<?> form) {
-         modal.getFeedbackPanel().refresh(target);
 -    private void selectVersion(final AjaxRequestTarget target, final 
ConnInstanceTO connInstanceTO,
 -            final AjaxDropDownChoicePanel<String> version, final String 
versionValue) {
 -
 -        connInstanceTO.setVersion(versionValue);
 -        target.add(version);
++    protected static ConnBundleTO getBundle(final ConnInstanceTO 
connInstanceTO, final List<ConnBundleTO> bundles) {
++        return CollectionUtils.find(bundles, new Predicate<ConnBundleTO>() {
+ 
 -        bundleTO = getSelectedBundleTO(connInstanceTO);
 -        properties = fillProperties(bundleTO, connInstanceTO);
 -        target.add(propertiesContainer);
 -    }
 -
 -    public List<ConnConfProperty> getProperties() {
 -        return properties;
++            @Override
++            public boolean evaluate(final ConnBundleTO bundle) {
++                return 
bundle.getBundleName().equals(connInstanceTO.getBundleName())
++                        && 
bundle.getVersion().equals(connInstanceTO.getVersion());
++            }
++        });
      }
  }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index 1cb987f,1cb987f..ca67bdb
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@@ -18,12 -18,12 +18,13 @@@
   */
  package org.apache.syncope.client.console.panels;
  
++import java.beans.IntrospectionException;
  import java.beans.PropertyDescriptor;
  import java.io.Serializable;
  import java.lang.reflect.Field;
++import java.lang.reflect.InvocationTargetException;
  import java.util.ArrayList;
  import java.util.Arrays;
--import java.util.Collections;
  import java.util.List;
  import org.apache.commons.lang3.StringUtils;
  import org.apache.syncope.client.console.commons.Constants;
@@@ -107,10 -107,10 +108,10 @@@ public final class ListViewPanel<T exte
  
          if (toBeIncluded.isEmpty()) {
              LOG.warn("No field has been retrieved from {}", 
reference.getName());
--            listOfItems = Collections.<T>emptyList();
++            listOfItems = new ArrayList<>();
          } else if (list == null || list.isEmpty()) {
              LOG.info("No item to be shown");
--            listOfItems = Collections.<T>emptyList();
++            listOfItems = new ArrayList<>();
          } else {
              listOfItems = list;
              if (LOG.isDebugEnabled()) {
@@@ -157,7 -157,7 +158,8 @@@
                                      ? new Label("field", StringUtils.EMPTY)
                                      : new Label("field", new 
ResourceModel(value.toString(), value.toString())));
  
--                        } catch (Exception e) {
++                        } catch (IntrospectionException | 
IllegalAccessException | IllegalArgumentException 
++                                | InvocationTargetException e) {
                              LOG.error("Error retrieving value for field {}", 
fieldItem.getModelObject(), e);
                              fieldItem.add(new Label("field", 
StringUtils.EMPTY));
                          }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b56c08ee/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --cc 
client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
index 0101895,1b536c4..cdce531
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
@@@ -19,100 -19,100 +19,47 @@@
  package org.apache.syncope.client.console.panels;
  
  import java.util.ArrayList;
--import java.util.Collections;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
--import org.apache.syncope.client.console.pages.BaseModalPage;
 -import org.apache.syncope.client.console.panels.ModalContent.ModalEvent;
--import 
org.apache.syncope.client.console.panels.ResourceDetailsPanel.DetailsModEvent;
  import org.apache.syncope.client.console.rest.ConnectorRestClient;
- import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal.ModalEvent;
--import 
org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel.MultiValueSelectorEvent;
--import 
org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView;
  import org.apache.syncope.common.lib.to.ResourceTO;
  import org.apache.syncope.common.lib.types.ConnConfProperty;
--import org.apache.wicket.ajax.AjaxRequestTarget;
--import org.apache.wicket.ajax.markup.html.form.AjaxButton;
--import org.apache.wicket.event.Broadcast;
--import org.apache.wicket.event.IEvent;
--import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
--import org.apache.wicket.markup.html.WebMarkupContainer;
--import org.apache.wicket.markup.html.form.Form;
--import org.apache.wicket.markup.html.list.ListView;
--import org.apache.wicket.markup.html.panel.Panel;
--import org.apache.wicket.model.PropertyModel;
--import org.apache.wicket.model.ResourceModel;
++import org.apache.wicket.model.IModel;
  import org.apache.wicket.spring.injection.annot.SpringBean;
  
--public class ResourceConnConfPanel extends Panel {
++public abstract class ResourceConnConfPanel extends 
AbstractConnectorConfPanel<ResourceTO> {
  
      private static final long serialVersionUID = -7982691107029848579L;
  
      @SpringBean
      private ConnectorRestClient restClient;
  
--    private final ResourceTO resourceTO;
--
      private final boolean createFlag;
  
--    private List<ConnConfProperty> connConfProperties;
--
--    private final WebMarkupContainer connConfPropContainer;
--
--    private final AjaxButton check;
--
--    public ResourceConnConfPanel(final String id, final ResourceTO 
resourceTO, final boolean createFlag) {
--        super(id);
--        setOutputMarkupId(true);
++    public ResourceConnConfPanel(final String id, final IModel<ResourceTO> 
model, final boolean createFlag) {
++        super(id, model);
  
          this.createFlag = createFlag;
--        this.resourceTO = resourceTO;
--
--        connConfProperties = getConnConfProperties();
--
--        connConfPropContainer = new 
WebMarkupContainer("connectorPropertiesContainer");
--        connConfPropContainer.setOutputMarkupId(true);
--        add(connConfPropContainer);
--
--        /*
--         * the list of overridable connector properties
--         */
--        final ListView<ConnConfProperty> connPropView = new 
ConnConfPropertyListView("connectorProperties",
--                new PropertyModel<List<ConnConfProperty>>(this, 
"connConfProperties"),
--                false, resourceTO.getConnConfProperties());
--        connPropView.setOutputMarkupId(true);
--        connConfPropContainer.add(connPropView);
--
--        check = new IndicatingAjaxButton("check", new ResourceModel("check")) 
{
  
--            private static final long serialVersionUID = 
-4199438518229098169L;
++        final List<ConnConfProperty> connConfProperties = 
getConnProperties(model.getObject());
++        model.getObject().getConnConfProperties().clear();
++        model.getObject().getConnConfProperties().addAll(connConfProperties);
  
--            @Override
--            public void onSubmit(final AjaxRequestTarget target, final 
Form<?> form) {
--                final ResourceTO to = (ResourceTO) form.getModelObject();
--
--                if (restClient.check(to)) {
--                    info(getString("success_connection"));
--                } else {
--                    error(getString("error_connection"));
--                }
--
--                ((BaseModalPage) 
getPage()).getFeedbackPanel().refresh(target);
--            }
--        };
++        setConfPropertyListView("connConfProperties", false);
  
          check.setEnabled(!connConfProperties.isEmpty());
          check.setVisible(!connConfProperties.isEmpty());
--
--        connConfPropContainer.add(check);
      }
  
      /**
       * Get overridable properties.
       *
++     * @param resourceTO resource instance.
       * @return overridable properties.
       */
--    private List<ConnConfProperty> getConnConfProperties() {
++    @Override
++    protected final List<ConnConfProperty> getConnProperties(final ResourceTO 
resourceTO) {
          List<ConnConfProperty> props = new ArrayList<>();
          Long connectorKey = resourceTO.getConnector();
          if (connectorKey != null && connectorKey > 0) {
@@@ -137,53 -137,53 +84,6 @@@
              }
          }
  
--        // re-order properties
--        Collections.sort(props);
--
          return props;
      }
--
--    @Override
--    public void onEvent(final IEvent<?> event) {
--        AjaxRequestTarget target = null;
--        if (event.getPayload() instanceof DetailsModEvent) {
--            // connector change: update properties and forward event
--            target = ((ModalEvent) event.getPayload()).getTarget();
--
--            connConfProperties = getConnConfProperties();
--            check.setEnabled(!connConfProperties.isEmpty());
--
--            target.add(connConfPropContainer);
--        } else if (event.getPayload() instanceof MultiValueSelectorEvent) {
--            // multi value connector property change: forward event
--            target = ((MultiValueSelectorEvent) 
event.getPayload()).getTarget();
--        }
--
--        if (target != null) {
--            send(getPage(), Broadcast.BREADTH, new ConnConfModEvent(target, 
connConfProperties));
--        }
--    }
--
--    /**
--     * Connector configuration properties modification event.
--     */
--    public static class ConnConfModEvent extends ModalEvent {
--
--        private final List<ConnConfProperty> configuration;
--
--        /**
--         * Constructor.
--         *
--         * @param target request target.
--         * @param configuration connector configuration properties.
--         */
--        public ConnConfModEvent(final AjaxRequestTarget target, final 
List<ConnConfProperty> configuration) {
--            super(target);
--            this.configuration = configuration;
--        }
--
--        public List<ConnConfProperty> getConfiguration() {
--            return configuration;
--        }
--    }
  }

Reply via email to