View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.console.wizards.resources;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.HashSet;
24  import java.util.List;
25  import java.util.Set;
26  import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
27  import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
28  import org.apache.syncope.client.console.rest.AnyTypeRestClient;
29  import org.apache.syncope.client.console.rest.ConnectorRestClient;
30  import org.apache.syncope.client.console.wizards.mapping.AbstractMappingPanel;
31  import org.apache.syncope.client.console.wizards.mapping.ItemTransformersTogglePanel;
32  import org.apache.syncope.client.console.wizards.mapping.JEXLTransformersTogglePanel;
33  import org.apache.syncope.client.ui.commons.Constants;
34  import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
35  import org.apache.syncope.common.lib.SyncopeConstants;
36  import org.apache.syncope.common.lib.to.AnyTypeClassTO;
37  import org.apache.syncope.common.lib.to.AnyTypeTO;
38  import org.apache.syncope.common.lib.to.ResourceTO;
39  import org.apache.syncope.common.lib.types.AnyTypeKind;
40  import org.apache.syncope.common.lib.types.MappingPurpose;
41  import org.apache.wicket.model.IModel;
42  import org.apache.wicket.model.LoadableDetachableModel;
43  import org.apache.wicket.model.util.ListModel;
44  import org.apache.wicket.spring.injection.annot.SpringBean;
45  import org.slf4j.Logger;
46  import org.slf4j.LoggerFactory;
47  
48  /**
49   * Resource mapping panel.
50   */
51  public class ResourceMappingPanel extends AbstractMappingPanel {
52  
53      private static final long serialVersionUID = -7982691107029848579L;
54  
55      protected static final Logger LOG = LoggerFactory.getLogger(ResourceMappingPanel.class);
56  
57      @SpringBean
58      protected ConnectorRestClient connectorRestClient;
59  
60      @SpringBean
61      protected AnyTypeRestClient anyTypeRestClient;
62  
63      @SpringBean
64      protected AnyTypeClassRestClient anyTypeClassRestClient;
65  
66      /**
67       * External resource provisioning configuration instance to be updated.
68       */
69      protected final ResourceProvision provision;
70  
71      protected final LoadableDetachableModel<List<String>> extAttrNames;
72  
73      /**
74       * Attribute Mapping Panel.
75       *
76       * @param id panel id
77       * @param resourceTO external resource to be updated
78       * @param adminRealm admin realm
79       * @param provision external resource provisioning configuration instance
80       * @param itemTransformers mapping item transformers toggle panel
81       * @param jexlTransformers JEXL transformers toggle panel
82       */
83      public ResourceMappingPanel(
84              final String id,
85              final ResourceTO resourceTO,
86              final String adminRealm,
87              final ResourceProvision provision,
88              final ItemTransformersTogglePanel itemTransformers,
89              final JEXLTransformersTogglePanel jexlTransformers) {
90  
91          super(id,
92                  itemTransformers,
93                  jexlTransformers,
94                  new ListModel<>(provision.getItems()),
95                  resourceTO.getConnector() != null,
96                  MappingPurpose.BOTH);
97  
98          setOutputMarkupId(true);
99  
100         this.provision = provision;
101 
102         extAttrNames = new LoadableDetachableModel<>() {
103 
104             private static final long serialVersionUID = 5275935387613157437L;
105 
106             @Override
107             protected List<String> load() {
108                 return connectorRestClient.getExtAttrNames(
109                         adminRealm,
110                         provision.getObjectClass(),
111                         resourceTO.getConnector(),
112                         resourceTO.getConfOverride());
113             }
114         };
115     }
116 
117     @Override
118     protected boolean hidePassword() {
119         return !AnyTypeKind.USER.name().equals(provision.getAnyType());
120     }
121 
122     @Override
123     protected IModel<List<String>> getExtAttrNames() {
124         return extAttrNames;
125     }
126 
127     @Override
128     protected void onBeforeRender() {
129         super.onBeforeRender();
130         passwordLabel.setVisible(AnyTypeKind.USER.name().equals(this.provision.getAnyType()));
131     }
132 
133     @Override
134     protected void setAttrNames(final AjaxTextFieldPanel toBeUpdated) {
135         toBeUpdated.setRequired(true);
136         toBeUpdated.setEnabled(true);
137 
138         Set<String> choices = new HashSet<>();
139         if (SyncopeConstants.REALM_ANYTYPE.equals(provision.getAnyType())) {
140             choices.add(Constants.KEY_FIELD_NAME);
141             choices.add("name");
142             choices.add("fullpath");
143         } else {
144             AnyTypeTO anyType = null;
145             try {
146                 anyType = anyTypeRestClient.read(provision.getAnyType());
147             } catch (Exception e) {
148                 LOG.error("Could not read AnyType {}", provision.getAnyType(), e);
149             }
150 
151             List<AnyTypeClassTO> anyTypeClassTOs = new ArrayList<>();
152             if (anyType != null) {
153                 try {
154                     anyTypeClassTOs.addAll(anyTypeClassRestClient.list(anyType.getClasses()));
155                 } catch (Exception e) {
156                     LOG.error("Could not read AnyType classes for {}", anyType.getClasses(), e);
157                 }
158             }
159             provision.getAuxClasses().forEach(auxClass -> {
160                 try {
161                     anyTypeClassTOs.add(anyTypeClassRestClient.read(auxClass));
162                 } catch (Exception e) {
163                     LOG.error("Could not read AnyTypeClass for {}", auxClass, e);
164                 }
165             });
166 
167             switch (provision.getAnyType()) {
168                 case "USER":
169                     choices.addAll(ClassPathScanImplementationLookup.USER_FIELD_NAMES);
170                     break;
171 
172                 case "GROUP":
173                     choices.addAll(ClassPathScanImplementationLookup.GROUP_FIELD_NAMES);
174                     break;
175 
176                 default:
177                     choices.addAll(ClassPathScanImplementationLookup.ANY_OBJECT_FIELD_NAMES);
178             }
179 
180             anyTypeClassTOs.forEach(anyTypeClassTO -> {
181                 choices.addAll(anyTypeClassTO.getPlainSchemas());
182                 choices.addAll(anyTypeClassTO.getDerSchemas());
183                 choices.addAll(anyTypeClassTO.getVirSchemas());
184             });
185         }
186 
187         List<String> names = new ArrayList<>(choices);
188         Collections.sort(names);
189         toBeUpdated.setChoices(names);
190     }
191 }