1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package edu.internet2.middleware.grouper.grouperUi.serviceLogic;
17
18 import java.io.InputStreamReader;
19 import java.io.Reader;
20 import java.sql.Timestamp;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.LinkedHashMap;
26 import java.util.LinkedHashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33
34 import org.apache.commons.csv.CSVRecord;
35 import org.apache.commons.fileupload.FileItem;
36 import org.apache.commons.lang.StringUtils;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40 import edu.internet2.middleware.grouper.Group;
41 import edu.internet2.middleware.grouper.GroupFinder;
42 import edu.internet2.middleware.grouper.GrouperSession;
43 import edu.internet2.middleware.grouper.GrouperSourceAdapter;
44 import edu.internet2.middleware.grouper.Member;
45 import edu.internet2.middleware.grouper.Membership;
46 import edu.internet2.middleware.grouper.MembershipFinder;
47 import edu.internet2.middleware.grouper.SubjectFinder;
48 import edu.internet2.middleware.grouper.audit.AuditEntry;
49 import edu.internet2.middleware.grouper.audit.AuditTypeBuiltin;
50 import edu.internet2.middleware.grouper.exception.GrouperSessionException;
51 import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiGroup;
52 import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiSubject;
53 import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiPaging;
54 import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiResponseJs;
55 import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction;
56 import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction.GuiMessageType;
57 import edu.internet2.middleware.grouper.grouperUi.beans.simpleMembershipUpdate.ImportSubjectWrapper;
58 import edu.internet2.middleware.grouper.grouperUi.beans.ui.GroupContainer;
59 import edu.internet2.middleware.grouper.grouperUi.beans.ui.GroupImportContainer;
60 import edu.internet2.middleware.grouper.grouperUi.beans.ui.GroupImportError;
61 import edu.internet2.middleware.grouper.grouperUi.beans.ui.GroupImportGroupSummary;
62 import edu.internet2.middleware.grouper.grouperUi.beans.ui.GrouperRequestContainer;
63 import edu.internet2.middleware.grouper.grouperUi.beans.ui.TextContainer;
64 import edu.internet2.middleware.grouper.grouperUi.serviceLogic.SimpleMembershipUpdateImportExport.GrouperImportException;
65 import edu.internet2.middleware.grouper.hibernate.AuditControl;
66 import edu.internet2.middleware.grouper.hibernate.GrouperTransactionType;
67 import edu.internet2.middleware.grouper.hibernate.HibernateHandler;
68 import edu.internet2.middleware.grouper.hibernate.HibernateHandlerBean;
69 import edu.internet2.middleware.grouper.hibernate.HibernateSession;
70 import edu.internet2.middleware.grouper.internal.dao.GrouperDAOException;
71 import edu.internet2.middleware.grouper.internal.dao.QueryOptions;
72 import edu.internet2.middleware.grouper.internal.util.GrouperUuid;
73 import edu.internet2.middleware.grouper.j2ee.GrouperRequestWrapper;
74 import edu.internet2.middleware.grouper.j2ee.GrouperUiRestServlet;
75 import edu.internet2.middleware.grouper.membership.MembershipType;
76 import edu.internet2.middleware.grouper.misc.GrouperDAOFactory;
77 import edu.internet2.middleware.grouper.misc.GrouperSessionHandler;
78 import edu.internet2.middleware.grouper.privs.AccessPrivilege;
79 import edu.internet2.middleware.grouper.ui.GrouperUiFilter;
80 import edu.internet2.middleware.grouper.ui.exceptions.ControllerDone;
81 import edu.internet2.middleware.grouper.ui.exceptions.NoSessionException;
82 import edu.internet2.middleware.grouper.ui.tags.GrouperPagingTag2;
83 import edu.internet2.middleware.grouper.ui.util.GrouperUiConfig;
84 import edu.internet2.middleware.grouper.ui.util.GrouperUiUserData;
85 import edu.internet2.middleware.grouper.ui.util.GrouperUiUtils;
86 import edu.internet2.middleware.grouper.ui.util.ProgressBean;
87 import edu.internet2.middleware.grouper.userData.GrouperUserDataApi;
88 import edu.internet2.middleware.grouper.util.GrouperCallable;
89 import edu.internet2.middleware.grouper.util.GrouperFuture;
90 import edu.internet2.middleware.grouper.util.GrouperUtil;
91 import edu.internet2.middleware.grouperClient.collections.MultiKey;
92 import edu.internet2.middleware.grouperClient.util.ExpirableCache;
93 import edu.internet2.middleware.subject.Subject;
94 import edu.internet2.middleware.subject.SubjectNotUniqueException;
95 import edu.internet2.middleware.subject.SubjectUtils;
96
97
98
99
100
101
102 public class UiV2GroupImport {
103
104
105
106 protected static final Log LOG = edu.internet2.middleware.grouper.util.GrouperUtil.getLog(UiV2GroupImport.class);
107
108
109
110
111
112
113 public void groupImportValidateList(HttpServletRequest request, HttpServletResponse response) {
114
115 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
116
117 GrouperSession grouperSession = null;
118
119 try {
120
121 grouperSession = GrouperSession.start(loggedInSubject);
122
123 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
124
125 String entityList = StringUtils.defaultString(request.getParameter("entityList"));
126
127
128 entityList = StringUtils.replace(entityList, ",", " ");
129 entityList = StringUtils.replace(entityList, ";", " ");
130
131 String[] entityIdOrIdentifiers = GrouperUtil.splitTrim(entityList, null, true);
132
133 if (GrouperUtil.length(entityIdOrIdentifiers) == 0) {
134
135 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
136 "#entityListId",
137 TextContainer.retrieveFromRequest().getText().get("groupImportNoEntitiesSpecified")));
138 return;
139
140 }
141
142 if (GrouperUtil.length(entityIdOrIdentifiers) > 100) {
143
144 guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error,
145 TextContainer.retrieveFromRequest().getText().get("groupImportTooManyEntitiesToValidate")));
146 return;
147
148 }
149
150
151 Set<GuiSubject> extraGuiSubjects = new LinkedHashSet<GuiSubject>();
152
153 GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupImportContainer().setGroupImportExtraGuiSubjects(extraGuiSubjects);
154
155 String source = request.getParameter("searchEntitySourceName");
156
157 List<String> entityIdOrIdentifiersList = new ArrayList<String>(Arrays.asList(GrouperUtil.nonNull(
158 entityIdOrIdentifiers, String.class)));
159
160 Map<String, Subject> entityIdOrIdentifierMap = null;
161
162 if (StringUtils.equals("all", source)) {
163
164 entityIdOrIdentifierMap = SubjectFinder.findByIdsOrIdentifiers(entityIdOrIdentifiersList);
165
166 } else {
167
168 entityIdOrIdentifierMap = SubjectFinder.findByIdsOrIdentifiers(entityIdOrIdentifiersList, source);
169
170 }
171
172
173 for (Subject subject : GrouperUtil.nonNull(entityIdOrIdentifierMap).values()) {
174 extraGuiSubjects.add(new GuiSubject(subject));
175 }
176
177
178 entityIdOrIdentifiersList.removeAll(GrouperUtil.nonNull(entityIdOrIdentifierMap).keySet());
179
180 if (entityIdOrIdentifiersList.size() > 0) {
181 GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupImportContainer().setEntityIdsNotFound(GrouperUtil.join(entityIdOrIdentifiersList.iterator(), ", "));
182
183 guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error,
184 TextContainer.retrieveFromRequest().getText().get("groupImportEntityIdsNotFound")));
185
186 }
187
188
189 guiResponseJs.addAction(GuiScreenAction.newScript(
190 "dijit.byId('groupAddMemberComboId').set('displayedValue', ''); " +
191 "dijit.byId('groupAddMemberComboId').set('value', '');"));
192
193
194 guiResponseJs.addAction(GuiScreenAction.newFormFieldValue("bulkAddOptions", "input"));
195
196
197 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#groupImportExtraMembersDivId",
198 "/WEB-INF/grouperUi2/groupImport/groupImportExtraSubjects.jsp"));
199
200 } finally {
201 GrouperSession.stopQuietly(grouperSession);
202 }
203
204
205 }
206
207
208
209
210
211
212
213 public void groupExportSubmit(HttpServletRequest request, HttpServletResponse response) {
214
215 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
216
217 GrouperSession grouperSession = null;
218
219 Group group = null;
220
221 try {
222
223 grouperSession = GrouperSession.start(loggedInSubject);
224
225 List<String> urlStrings = GrouperUiRestServlet.extractUrlStrings(request);
226
227
228 String groupIdString = urlStrings.get(2);
229
230 String groupId = GrouperUtil.prefixOrSuffix(groupIdString, "=", false);
231
232 group = GroupFinder.findByUuid(grouperSession, groupId, false);
233
234 if (group == null) {
235 throw new RuntimeException("Cant find group by id: " + groupId);
236 }
237
238 GroupContainer groupContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer();
239 GroupImportContainer groupImportContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupImportContainer();
240
241 groupContainer.setGuiGroup(new GuiGroup(group));
242
243 if (!groupContainer.isCanRead()) {
244 throw new RuntimeException("Cant read group: " + group.getName());
245 }
246
247
248 String groupExportOptions = urlStrings.get(3);
249
250 boolean exportAll = false;
251 if (StringUtils.equals("all", groupExportOptions)) {
252 groupImportContainer.setExportAll(true);
253 exportAll = true;
254 } else if (StringUtils.equals("ids", groupExportOptions)) {
255 groupImportContainer.setExportAll(false);
256 } else {
257 throw new RuntimeException("Not expecting group-export-options value: '" + groupExportOptions + "'");
258 }
259
260
261
262 @SuppressWarnings("unused")
263 String fileName = urlStrings.get(4);
264
265 if (exportAll) {
266 String headersCommaSeparated = GrouperUiConfig.retrieveConfig().propertyValueString(
267 "uiV2.group.exportAllSubjectFields");
268
269 String exportAllSortField = GrouperUiConfig.retrieveConfig().propertyValueString(
270 "uiV2.group.exportAllSortField");
271
272 SimpleMembershipUpdateImportExport.exportGroupAllFieldsToBrowser(group, headersCommaSeparated, exportAllSortField, false);
273 } else {
274
275 SimpleMembershipUpdateImportExport.exportGroupSubjectIdsCsv(group, false);
276
277 }
278
279 GrouperUserDataApi.recentlyUsedGroupAdd(GrouperUiUserData.grouperUiGroupNameForUserData(),
280 loggedInSubject, group);
281
282 } finally {
283 GrouperSession.stopQuietly(grouperSession);
284 }
285
286 }
287
288
289
290
291
292
293 public void groupExport(HttpServletRequest request, HttpServletResponse response) {
294
295 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
296
297 GrouperSession grouperSession = null;
298
299 Group group = null;
300
301 try {
302
303 grouperSession = GrouperSession.start(loggedInSubject);
304
305 group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.READ).getGroup();
306
307 if (group == null) {
308 return;
309 }
310
311 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
312
313 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId",
314 "/WEB-INF/grouperUi2/groupImport/groupExport.jsp"));
315
316 } finally {
317 GrouperSession.stopQuietly(grouperSession);
318 }
319 }
320
321
322
323
324
325
326
327 public void groupExportTypeChange(HttpServletRequest request, HttpServletResponse response) {
328
329 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
330
331 GrouperSession grouperSession = null;
332
333 Group group = null;
334
335 try {
336
337 grouperSession = GrouperSession.start(loggedInSubject);
338
339 group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.READ).getGroup();
340
341 if (group == null) {
342 return;
343 }
344
345 String groupExportOptions = request.getParameter("group-export-options[]");
346
347 GroupImportContainer groupImportContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupImportContainer();
348
349 if (StringUtils.equals("all", groupExportOptions)) {
350 groupImportContainer.setExportAll(true);
351 } else if (StringUtils.equals("ids", groupExportOptions)) {
352 groupImportContainer.setExportAll(false);
353 } else {
354 throw new RuntimeException("Not expecting group-export-options value: '" + groupExportOptions + "'");
355 }
356
357 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
358
359 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#formActionsDivId",
360 "/WEB-INF/grouperUi2/groupImport/groupExportButtons.jsp"));
361
362 } finally {
363 GrouperSession.stopQuietly(grouperSession);
364 }
365 }
366
367
368
369
370
371
372
373
374
375
376
377 private boolean groupImportSetupExtraGroups(Subject loggedInSubject,
378 HttpServletRequest request, GuiResponseJs guiResponseJs, boolean considerRemoveGroupId, boolean includeCombobox,
379 Set<Group> allGroups, boolean errorOnNullCombobox) {
380
381 Set<GuiGroup> extraGuiGroups = new LinkedHashSet<GuiGroup>();
382
383 GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupImportContainer().setGroupImportExtraGuiGroups(extraGuiGroups);
384
385 String removeGroupId = null;
386
387
388 if (considerRemoveGroupId) {
389 removeGroupId = request.getParameter("removeGroupId");
390 if (StringUtils.isBlank(removeGroupId)) {
391 throw new RuntimeException("Why would removeGroupId be empty????");
392 }
393 }
394
395
396 String comboValue = request.getParameter("groupImportGroupComboName");
397
398 if (StringUtils.isBlank(comboValue)) {
399
400 comboValue = request.getParameter("groupImportGroupComboNameDisplay");
401 }
402
403 Group theGroup = StringUtils.isBlank(comboValue) ? null : new GroupFinder()
404 .assignPrivileges(AccessPrivilege.UPDATE_PRIVILEGES)
405 .assignSubject(loggedInSubject)
406 .assignFindByUuidOrName(true).assignScope(comboValue).findGroup();
407
408 boolean success = true;
409
410 if (theGroup == null) {
411 if (includeCombobox && errorOnNullCombobox) {
412 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
413 "#groupImportGroupComboErrorId",
414 TextContainer.retrieveFromRequest().getText().get("groupImportGroupNotFound")));
415 success = false;
416 }
417
418 } else {
419 if (includeCombobox) {
420 extraGuiGroups.add(new GuiGroup(theGroup));
421 }
422
423 allGroups.add(theGroup);
424 }
425
426
427
428 for (int i=0;i<100;i++) {
429 String extraGroupId = request.getParameter("extraGroupId_" + i);
430
431
432 if (StringUtils.isBlank(extraGroupId)) {
433 break;
434 }
435
436
437 if (considerRemoveGroupId && StringUtils.equals(removeGroupId, extraGroupId)) {
438 continue;
439 }
440
441 theGroup = new GroupFinder()
442 .assignPrivileges(AccessPrivilege.UPDATE_PRIVILEGES)
443 .assignSubject(loggedInSubject)
444 .assignFindByUuidOrName(true).assignScope(extraGroupId).findGroup();
445
446 extraGuiGroups.add(new GuiGroup(theGroup));
447
448
449 allGroups.add(theGroup);
450
451 }
452 return success;
453 }
454
455
456
457
458
459 private static ExpirableCache<MultiKey, GroupImportContainer> importThreadProgress = new ExpirableCache<MultiKey, GroupImportContainer>(300);
460
461
462
463
464
465
466 public void groupImportSubmit(HttpServletRequest request, HttpServletResponse response) {
467
468 Map<String, Object> debugMap = new LinkedHashMap<String, Object>();
469 long startNanos = System.nanoTime();
470
471 debugMap.put("method", "groupImportSubmit");
472
473 try {
474 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
475
476 GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate();
477
478 final GroupImportContainer groupImportContainer = grouperRequestContainer.getGroupImportContainer();
479
480 String sessionId = request.getSession().getId();
481
482 debugMap.put("sessionId", GrouperUtil.abbreviate(sessionId, 8));
483
484
485
486 String uniqueImportId = GrouperUuid.getUuid();
487
488 debugMap.put("uniqueImportId", GrouperUtil.abbreviate(uniqueImportId, 8));
489
490 groupImportContainer.setUniqueImportId(uniqueImportId);
491
492 MultiKey reportMultiKey = new MultiKey(sessionId, uniqueImportId);
493
494 importThreadProgress.put(reportMultiKey, groupImportContainer);
495
496 GrouperSession grouperSession = null;
497
498 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
499
500 final String bulkAddOption = request.getParameter("bulkAddOptions");
501
502
503
504 final Set<Group> groups = new LinkedHashSet<Group>();
505 final Set<Subject> subjectSet = new LinkedHashSet<Subject>();
506 final Map<String, Integer> listInvalidSubjectIdsAndRow = new LinkedHashMap<String, Integer>();
507
508 final boolean importReplaceMembers = GrouperUtil.booleanValue(request.getParameter("replaceExistingMembers"), false);
509 final boolean removeMembers = GrouperUtil.booleanValue(request.getParameter("removeMembers"), false);
510
511 final Timestamp startDate;
512 try {
513 String startDateString = request.getParameter("startDate");
514 startDate = GrouperUtil.stringToTimestampTimeRequiredWithoutSeconds(startDateString);
515 } catch (Exception e) {
516 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
517 "#member-start-date",
518 TextContainer.retrieveFromRequest().getText().get("groupImportFromDateInvalid")));
519 return;
520 }
521
522 final Timestamp endDate;
523 try {
524 String endDateString = request.getParameter("endDate");
525 endDate = GrouperUtil.stringToTimestampTimeRequiredWithoutSeconds(endDateString);
526 } catch (Exception e) {
527 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
528 "#member-end-date",
529 TextContainer.retrieveFromRequest().getText().get("groupImportToDateInvalid")));
530 return;
531 }
532
533 if (startDate != null && endDate != null && !endDate.after(startDate)) {
534 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
535 "#member-end-date",
536 TextContainer.retrieveFromRequest().getText().get("groupImportToDateAfterFromDateError")));
537 return;
538 }
539
540 final Object[] csvEntriesObject = new Object[1];
541
542 final String[] fileName = new String[1];
543
544 try {
545 grouperSession = GrouperSession.start(loggedInSubject);
546
547 boolean success = groupImportSetupExtraGroups(loggedInSubject, request, guiResponseJs, false, true, groups, false);
548
549 if (!success) {
550
551 return;
552 }
553
554
555 debugMap.put("groups", groups.size());
556
557 if (groups.size() == 0) {
558 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
559 "#groupImportGroupComboErrorId",
560 TextContainer.retrieveFromRequest().getText().get("groupImportGroupNotFound")));
561 return;
562 }
563
564
565 debugMap.put("bulkAddOption", bulkAddOption);
566
567 if (StringUtils.equals(bulkAddOption, "import")) {
568
569 GrouperRequestWrapper grouperRequestWrapper = GrouperRequestWrapper.retrieveGrouperRequestWrapper(request);
570
571 FileItem importCsvFile = grouperRequestWrapper.getParameterFileItem("importCsvFile");
572
573 if (importCsvFile == null) {
574
575 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
576 "#importCsvFileId",
577 TextContainer.retrieveFromRequest().getText().get("groupImportUploadFile")));
578 return;
579 }
580
581 Reader reader = null;
582 reader = new InputStreamReader(importCsvFile.getInputStream());
583
584 fileName[0] = StringUtils.defaultString(importCsvFile == null ? "" : importCsvFile.getName());
585
586 try {
587
588 List<CSVRecord> csvEntries = SimpleMembershipUpdateImportExport.parseCsvImportFileToCsv(reader, fileName[0]);
589 debugMap.put("csvEntries", GrouperUtil.length(csvEntries));
590 csvEntriesObject[0] = csvEntries;
591 } catch (GrouperImportException gie) {
592 if (LOG.isDebugEnabled()) {
593 LOG.debug("error in import", gie);
594 }
595 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
596 "#importCsvFileId", GrouperUtil.xmlEscape(gie.getMessage())));
597 return;
598 }
599
600 } else if (StringUtils.equals(bulkAddOption, "input")) {
601
602
603 success = groupImportSetupExtraSubjects(loggedInSubject, request, guiResponseJs, false, true, subjectSet, false);
604
605 if (!success) {
606
607 return;
608 }
609
610 if (subjectSet.size() == 0) {
611 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
612 "#groupAddMemberComboErrorId",
613 TextContainer.retrieveFromRequest().getText().get("groupImportSubjectNotFound")));
614 return;
615 }
616
617
618 } else if (StringUtils.equals(bulkAddOption, "list")) {
619
620 String entityList = StringUtils.defaultString(request.getParameter("entityList"));
621
622
623 entityList = StringUtils.replace(entityList, ",", " ");
624 entityList = StringUtils.replace(entityList, ";", " ");
625
626 String[] entityIdOrIdentifiers = GrouperUtil.splitTrim(entityList, null, true);
627
628 debugMap.put("entityIdOrIdentifiers", GrouperUtil.length(entityIdOrIdentifiers));
629 if (GrouperUtil.length(entityIdOrIdentifiers) == 0) {
630
631 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
632 "#entityListId",
633 TextContainer.retrieveFromRequest().getText().get("groupImportNoEntitiesSpecified")));
634 return;
635
636 }
637
638 String source = request.getParameter("searchEntitySourceName");
639
640 List<String> entityIdOrIdentifiersList = new ArrayList<String>(Arrays.asList(GrouperUtil.nonNull(
641 entityIdOrIdentifiers, String.class)));
642
643 Map<String, Subject> entityIdOrIdentifierMap = null;
644
645 if (StringUtils.equals("all", source)) {
646
647 entityIdOrIdentifierMap = SubjectFinder.findByIdsOrIdentifiers(entityIdOrIdentifiersList);
648
649 } else {
650
651 entityIdOrIdentifierMap = SubjectFinder.findByIdsOrIdentifiers(entityIdOrIdentifiersList, source);
652
653 }
654
655
656 subjectSet.addAll(GrouperUtil.nonNull(entityIdOrIdentifierMap).values());
657
658
659 List<String> originalIdList = new ArrayList<String>(entityIdOrIdentifiersList);
660
661
662 entityIdOrIdentifiersList.removeAll(GrouperUtil.nonNull(entityIdOrIdentifierMap).keySet());
663
664
665 for (String invalidId : entityIdOrIdentifiersList) {
666 int index = originalIdList.indexOf(invalidId);
667 listInvalidSubjectIdsAndRow.put(invalidId, index == -1 ? null : index);
668 }
669
670 } else {
671 throw new RuntimeException("Not expecting bulk add option: " + bulkAddOption);
672 }
673
674 {
675 Group group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.UPDATE, false).getGroup();
676 if (group != null) {
677 groupImportContainer.setImportFromGroup(true);
678 groupImportContainer.setGroupId(group.getId());
679 }
680 }
681 {
682 Subject subject = UiV2Subject.retrieveSubjectHelper(request, false);
683 if (subject != null) {
684 groupImportContainer.setImportFromSubject(true);
685 groupImportContainer.setSubjectId(subject.getId());
686 groupImportContainer.setSourceId(subject.getSourceId());
687 }
688 }
689
690 if (importReplaceMembers && removeMembers) {
691 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
692 "#replaceExistingMembersId",
693 TextContainer.retrieveFromRequest().getText().get("groupImportCantReplaceAndRemove")));
694 return;
695 }
696
697 Iterator<Group> groupIterator = groups.iterator();
698
699
700
701
702
703 while (groupIterator.hasNext()) {
704
705 final Group group = groupIterator.next();
706
707 {
708
709 boolean canView = (Boolean)GrouperSession.callbackGrouperSession(
710 GrouperSession.staticGrouperSession().internal_getRootSession(), new GrouperSessionHandler() {
711
712 @Override
713 public Object callback(GrouperSession grouperSession) throws GrouperSessionException {
714 return group.canHavePrivilege(loggedInSubject, AccessPrivilege.VIEW.getName(), false);
715 }
716 });
717
718 if (!canView) {
719 guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error,
720 TextContainer.retrieveFromRequest().getText().get("groupImportGroupCantView")));
721 groupIterator.remove();
722 continue;
723 }
724 }
725
726 {
727
728 boolean canUpdate = (Boolean)GrouperSession.callbackGrouperSession(
729 GrouperSession.staticGrouperSession().internal_getRootSession(), new GrouperSessionHandler() {
730
731 @Override
732 public Object callback(GrouperSession grouperSession) throws GrouperSessionException {
733 return group.canHavePrivilege(loggedInSubject, AccessPrivilege.UPDATE.getName(), false);
734 }
735 });
736
737 if (!canUpdate) {
738 guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error,
739 TextContainer.retrieveFromRequest().getText().get("groupImportGroupCantUpdate")));
740 continue;
741 }
742 }
743 }
744
745 } catch (Exception e) {
746 throw new RuntimeException("error", e);
747
748
749 } finally {
750 GrouperSession.stopQuietly(grouperSession);
751 }
752
753 GrouperCallable<Void> grouperCallable = new GrouperCallable<Void>("groupImportMembers") {
754
755 @Override
756 public Void callLogic() {
757 try {
758 groupImportContainer.getProgressBean().setStartedMillis(System.currentTimeMillis());
759
760 UiV2GroupImport.this.groupImportSubmitHelper(loggedInSubject, groupImportContainer, groups, subjectSet,
761 listInvalidSubjectIdsAndRow, removeMembers, importReplaceMembers, bulkAddOption, fileName[0], (List<CSVRecord>)csvEntriesObject[0],
762 startDate, endDate);
763 } catch (RuntimeException re) {
764 groupImportContainer.getProgressBean().setHasException(true);
765
766 LOG.error("error", re);
767 } finally {
768
769 groupImportContainer.getProgressBean().setComplete(true);
770 }
771 return null;
772 }
773 };
774
775
776 boolean useThreads = GrouperUiConfig.retrieveConfig().propertyValueBooleanRequired("grouperUi.import.useThread");
777 debugMap.put("useThreads", useThreads);
778
779 if (useThreads) {
780
781 GrouperFuture<Void> grouperFuture = GrouperUtil.executorServiceSubmit(GrouperUtil.retrieveExecutorService(), grouperCallable);
782
783 Integer waitForCompleteForSeconds = GrouperUiConfig.retrieveConfig().propertyValueInt("grouperUi.import.progressStartsInSeconds");
784 debugMap.put("waitForCompleteForSeconds", waitForCompleteForSeconds);
785
786 GrouperFuture.waitForJob(grouperFuture, waitForCompleteForSeconds);
787
788 debugMap.put("threadAlive", !grouperFuture.isDone());
789
790 } else {
791 grouperCallable.callLogic();
792 }
793
794 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId",
795 "/WEB-INF/grouperUi2/groupImport/groupImportReportWrapper.jsp"));
796
797 groupImportReportStatusHelper(sessionId, uniqueImportId);
798 } catch (RuntimeException re) {
799 debugMap.put("exception", GrouperUtil.getFullStackTrace(re));
800 throw re;
801 } finally {
802 if (LOG.isDebugEnabled()) {
803 debugMap.put("tookMillis", (System.nanoTime()-startNanos)/1000000);
804 LOG.debug(GrouperUtil.mapToString(debugMap));
805 }
806 }
807 }
808
809
810
811
812
813
814 public void groupImportReportStatus(HttpServletRequest request, HttpServletResponse response) {
815 String sessionId = request.getSession().getId();
816 String uniqueImportId = request.getParameter("uniqueImportId");
817 groupImportReportStatusHelper(sessionId, uniqueImportId);
818 }
819
820
821
822
823
824
825 private void groupImportReportStatusHelper(String sessionId, String uniqueImportId) {
826
827 Map<String, Object> debugMap = new LinkedHashMap<String, Object>();
828
829 debugMap.put("method", "groupImportReportStatus");
830 debugMap.put("sessionId", GrouperUtil.abbreviate(sessionId, 8));
831 debugMap.put("uniqueImportId", GrouperUtil.abbreviate(uniqueImportId, 8));
832
833 long startNanos = System.nanoTime();
834 try {
835 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
836
837 MultiKey reportMultiKey = new MultiKey(sessionId, uniqueImportId);
838
839 GroupImportContainer groupImportContainer = importThreadProgress.get(reportMultiKey);
840
841 GrouperRequestContainer.retrieveFromRequestOrCreate().setGroupImportContainer(groupImportContainer);
842
843
844 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#id_"+uniqueImportId,
845 "/WEB-INF/grouperUi2/groupImport/groupImportReport.jsp"));
846
847
848 debugMap.put("percentComplete", groupImportContainer.getProgressBean().getPercentComplete());
849 debugMap.put("progressCompleteRecords", groupImportContainer.getProgressBean().getProgressCompleteRecords());
850 debugMap.put("progressTotalRecords", groupImportContainer.getProgressBean().getProgressTotalRecords());
851
852
853 if (groupImportContainer != null) {
854
855
856 if (groupImportContainer.getProgressBean().isThisLastStatus()) {
857 return;
858 }
859
860 if (groupImportContainer.getProgressBean().isHasException()) {
861 guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error,
862 TextContainer.retrieveFromRequest().getText().get("groupImportException")));
863
864 importThreadProgress.put(reportMultiKey, null);
865 return;
866 }
867
868 debugMap.put("complete", groupImportContainer.getProgressBean().isComplete());
869 if (!groupImportContainer.getProgressBean().isComplete()) {
870 int progressRefreshSeconds = GrouperUiConfig.retrieveConfig().propertyValueInt("grouperUi.import.progressRefreshSeconds");
871 progressRefreshSeconds = Math.max(progressRefreshSeconds, 1);
872 progressRefreshSeconds *= 1000;
873 guiResponseJs.addAction(GuiScreenAction.newScript("setTimeout(function() {ajax('../app/UiV2GroupImport.groupImportReportStatus?uniqueImportId=" + uniqueImportId + "')}, " + progressRefreshSeconds + ")"));
874 } else {
875
876 importThreadProgress.put(reportMultiKey, null);
877 }
878 }
879 } catch (RuntimeException re) {
880 debugMap.put("exception", GrouperUtil.getFullStackTrace(re));
881 throw re;
882 } finally {
883 if (LOG.isDebugEnabled()) {
884 debugMap.put("tookMillis", (System.nanoTime()-startNanos)/1000000);
885 LOG.debug(GrouperUtil.mapToString(debugMap));
886 }
887 }
888
889
890 }
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906 private void groupImportSubmitHelper(final Subject loggedInSubject, final GroupImportContainer groupImportContainer,
907 final Set<Group> groups, final Set<Subject> subjectSet, Map<String, Integer> listInvalidSubjectIdsAndRow,
908 boolean removeMembers, boolean importReplaceMembers, String bulkAddOption, String fileName, List<CSVRecord> csvEntries,
909 Timestamp startDate, Timestamp endDate) {
910
911 Map<String, Object> debugMap = new LinkedHashMap<String, Object>();
912
913 debugMap.put("method", "groupImportSubmit");
914
915 GrouperSession grouperSession = null;
916
917 int pauseBetweenRecordsMillis = GrouperUiConfig.retrieveConfig().propertyValueIntRequired("grouperUi.import.pauseInBetweenRecordsMillis");
918
919 try {
920 grouperSession = GrouperSession.start(loggedInSubject);
921
922 ProgressBean progressBean = groupImportContainer.getProgressBean();
923
924 if (GrouperUtil.length(subjectSet) == 0 && csvEntries != null) {
925 subjectSet.addAll(SimpleMembershipUpdateImportExport.parseCsvImportFile(csvEntries, new ArrayList<String>(),
926 listInvalidSubjectIdsAndRow, true));
927 }
928
929 Iterator<Group> groupIterator = groups.iterator();
930
931 Set<GuiGroup> guiGroups = new LinkedHashSet<GuiGroup>();
932 groupImportContainer.setGuiGroups(guiGroups);
933
934 progressBean.setProgressTotalRecords(GrouperUtil.length(groups) * GrouperUtil.length(subjectSet));
935
936
937 while (groupIterator.hasNext()) {
938
939 final Group group = groupIterator.next();
940
941 guiGroups.add(new GuiGroup(group));
942
943 GroupImportGroupSummarypImportGroupSummary.html#GroupImportGroupSummary">GroupImportGroupSummary groupImportGroupSummary = new GroupImportGroupSummary();
944 groupImportContainer.getGroupImportGroupSummaryForGroupMap().put(group, groupImportGroupSummary);
945
946 List<Member> existingMembers = new ArrayList<Member>(GrouperUtil.nonNull(group.getImmediateMembers()));
947 List<Subject> subjectList = new ArrayList<Subject>(GrouperUtil.nonNull(subjectSet));
948 groupImportGroupSummary.setGroupCountOriginal(GrouperUtil.length(existingMembers));
949
950 if (removeMembers) {
951
952 Set<Object[]> membershipsResult = MembershipFinder.findMemberships(GrouperUtil.toList(group.getId()), null, null, MembershipType.IMMEDIATE, Group.getDefaultList(), null, null, null, null, false);
953 for (Object[] membershipResult : membershipsResult) {
954 existingMembers.add((Member)membershipResult[2]);
955 }
956 }
957
958 List<Member> overlappingMembers = new ArrayList<Member>(GrouperUtil.nonNull(GrouperUiUtils.removeOverlappingSubjects(existingMembers, subjectList)));
959
960
961 if (listInvalidSubjectIdsAndRow.size() > 0) {
962 for (String subjectLabel : listInvalidSubjectIdsAndRow.keySet()) {
963 int rowNumber = listInvalidSubjectIdsAndRow.get(subjectLabel);
964
965 GroupImportError/beans/ui/GroupImportError.html#GroupImportError">GroupImportError groupImportError = new GroupImportError(subjectLabel, TextContainer.retrieveFromRequest().getText().get(
966 "groupImportProblemFindingSubjectError"), rowNumber);
967
968 groupImportGroupSummary.getGroupImportErrors().add(groupImportError);
969
970 groupImportGroupSummary.groupCountErrorsIncrement();
971 }
972 }
973
974 if (!removeMembers) {
975 progressBean.addProgressCompleteRecords(GrouperUtil.length(subjectSet) - GrouperUtil.length(subjectList));
976
977 for (int i=0;i<subjectList.size();i++) {
978
979 Subject subject = subjectList.get(i);
980
981 boolean hasError = false;
982 if (subject instanceof ImportSubjectWrapper) {
983 try {
984 subject = ((ImportSubjectWrapper)subject).wrappedSubject();
985 } catch (Exception e) {
986 int rowNumber = ((ImportSubjectWrapper)subject).getRow();
987 String label = ImportSubjectWrapper.errorLabelForRowStatic(rowNumber, ((ImportSubjectWrapper)subject).getRowData());
988 GroupImportError/beans/ui/GroupImportError.html#GroupImportError">GroupImportError groupImportError = new GroupImportError(label, TextContainer.retrieveFromRequest().getText().get(
989 "groupImportProblemFindingSubjectError"), rowNumber);
990
991 groupImportGroupSummary.getGroupImportErrors().add(groupImportError);
992
993 groupImportGroupSummary.groupCountErrorsIncrement();
994 hasError = true;
995 }
996 }
997
998 try {
999
1000 group.internal_addMember(subject, Group.getDefaultList(), false, null, startDate, endDate);
1001 GrouperUtil.sleep(pauseBetweenRecordsMillis);
1002 groupImportGroupSummary.groupCountAddedIncrement();
1003 } catch (Exception e) {
1004 if (!hasError) {
1005
1006 String subjectString = SubjectUtils.subjectToString(subject);
1007
1008 GroupImportError/beans/ui/GroupImportError.html#GroupImportError">GroupImportError groupImportError = new GroupImportError(subjectString, GrouperUtil.xmlEscape(e.getMessage()));
1009 groupImportGroupSummary.getGroupImportErrors().add(groupImportError);
1010
1011 groupImportGroupSummary.groupCountErrorsIncrement();
1012 LOG.warn("error with " + subjectString, e);
1013 }
1014 }
1015 progressBean.addProgressCompleteRecords(1);
1016
1017 }
1018 } else {
1019 progressBean.addProgressCompleteRecords(GrouperUtil.length(subjectSet) - GrouperUtil.length(overlappingMembers));
1020
1021 for (int i=0;i<overlappingMembers.size();i++) {
1022
1023 Member member = overlappingMembers.get(i);
1024
1025 try {
1026
1027
1028 group.deleteMember(member, false);
1029 GrouperUtil.sleep(pauseBetweenRecordsMillis);
1030
1031 groupImportGroupSummary.groupCountDeletedIncrement();
1032 } catch (Exception e) {
1033 String subjectString = SubjectUtils.subjectToString(member.getSubject());
1034 GroupImportError/beans/ui/GroupImportError.html#GroupImportError">GroupImportError groupImportError = new GroupImportError(subjectString, GrouperUtil.xmlEscape(e.getMessage()));
1035 groupImportGroupSummary.getGroupImportErrors().add(groupImportError);
1036 groupImportGroupSummary.groupCountErrorsIncrement();
1037 LOG.warn("error with " + subjectString, e);
1038 }
1039
1040 progressBean.addProgressCompleteRecords(1);
1041
1042 }
1043
1044 }
1045
1046 if (!removeMembers && overlappingMembers.size() > 0) {
1047
1048 Set<Membership> overlappingMemberships = group.getImmediateMemberships(Group.getDefaultList(), overlappingMembers);
1049
1050 Map<String, Membership> overlappingMembershipsMap = new LinkedHashMap<String, Membership>();
1051 for (Membership overlappingMembership : overlappingMemberships) {
1052 overlappingMembershipsMap.put(overlappingMembership.getMemberUuid(), overlappingMembership);
1053 }
1054
1055
1056 for (Member overlappingMember : overlappingMembers) {
1057 Membership overlappingMembership = overlappingMembershipsMap.get(overlappingMember.getUuid());
1058 if (overlappingMembership != null) {
1059 if (!GrouperUtil.equals(overlappingMembership.getEnabledTime(), startDate) ||
1060 !GrouperUtil.equals(overlappingMembership.getDisabledTime(), endDate)) {
1061
1062 try {
1063 overlappingMembership.setEnabledTime(startDate);
1064 overlappingMembership.setDisabledTime(endDate);
1065 GrouperDAOFactory.getFactory().getMembership().update(overlappingMembership);
1066 GrouperUtil.sleep(pauseBetweenRecordsMillis);
1067 groupImportGroupSummary.groupCountUpdatedIncrement();
1068 } catch (Exception e) {
1069 String subjectString = SubjectUtils.subjectToString(overlappingMember.getSubject());
1070 GroupImportError/beans/ui/GroupImportError.html#GroupImportError">GroupImportError groupImportError = new GroupImportError(subjectString, GrouperUtil.xmlEscape(e.getMessage()));
1071 groupImportGroupSummary.getGroupImportErrors().add(groupImportError);
1072 groupImportGroupSummary.groupCountErrorsIncrement();
1073 LOG.warn("error with " + subjectString, e);
1074 }
1075 }
1076 }
1077 }
1078 }
1079
1080 boolean didntImportDueToSubjects = groupImportGroupSummary.getGroupCountErrors() > 0;
1081
1082
1083 if (importReplaceMembers && !didntImportDueToSubjects && !removeMembers) {
1084
1085 progressBean.addProgressCompleteRecords(GrouperUtil.length(subjectSet) - GrouperUtil.length(existingMembers));
1086 for (Member existingMember : existingMembers) {
1087
1088 try {
1089 group.deleteMember(existingMember, false);
1090 GrouperUtil.sleep(pauseBetweenRecordsMillis);
1091 groupImportGroupSummary.groupCountDeletedIncrement();
1092 } catch (Exception e) {
1093
1094
1095 String subjectString = SubjectUtils.subjectToString(existingMember.getSubject());
1096 GroupImportError/beans/ui/GroupImportError.html#GroupImportError">GroupImportError groupImportError = new GroupImportError(subjectString, GrouperUtil.xmlEscape(e.getMessage()));
1097 groupImportGroupSummary.getGroupImportErrors().add(groupImportError);
1098 groupImportGroupSummary.groupCountErrorsIncrement();
1099 LOG.warn("error with " + subjectString, e);
1100
1101 }
1102 progressBean.addProgressCompleteRecords(1);
1103 }
1104 }
1105
1106
1107 int newSize = group.getImmediateMembers().size();
1108
1109 groupImportGroupSummary.setGroupCountNew(newSize);
1110
1111 try {
1112 GrouperUserDataApi.recentlyUsedGroupAdd(GrouperUiUserData.grouperUiGroupNameForUserData(),
1113 loggedInSubject, group);
1114 } catch (Exception e) {
1115 LOG.warn("Cant add recently used group: " + group.getName() + ", for subject: " + SubjectUtils.subjectToString(loggedInSubject) + ", maybe a priv was lost after import started???", e);
1116 }
1117
1118 if (StringUtils.equals(bulkAddOption, "import")) {
1119 auditImport(group.getUuid(), group.getName(), fileName, groupImportGroupSummary.getGroupCountAdded(), groupImportGroupSummary.getGroupCountDeleted(), groupImportGroupSummary.getGroupCountUpdated());
1120 }
1121
1122 groupImportGroupSummary.setComplete(true);
1123 }
1124
1125 progressBean.setProgressCompleteRecords(progressBean.getProgressTotalRecords());
1126
1127
1128 } catch (NoSessionException se) {
1129 throw se;
1130 } catch (ControllerDone cd) {
1131 throw cd;
1132 } finally {
1133 GrouperSession.stopQuietly(grouperSession);
1134 }
1135 }
1136
1137 private void auditImport(final String groupId, final String groupName, final String fileName,
1138 final int countAdded, final int countDeleted, final int countUpdated) {
1139 HibernateSession.callbackHibernateSession(
1140 GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT,
1141 new HibernateHandler() {
1142 public Object callback(HibernateHandlerBean hibernateHandlerBean)
1143 throws GrouperDAOException {
1144
1145 AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.MEMBERSHIP_GROUP_IMPORT, "file", fileName, "totalAdded",
1146 String.valueOf(countAdded), "groupId", groupId, "groupName", groupName, "totalDeleted", String.valueOf(countDeleted));
1147
1148 String description = "Added : " + countAdded + " subjects, updated " + countUpdated + " subjects"
1149 + " and deleted "+countDeleted + " subjects in group "+groupName;
1150 auditEntry.setDescription(description);
1151 auditEntry.saveOrUpdate(true);
1152
1153 return null;
1154 }
1155 });
1156 }
1157
1158
1159
1160
1161
1162
1163
1164 public void groupImportGroupSearch(HttpServletRequest request, HttpServletResponse response) {
1165
1166 GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate();
1167
1168 GroupContainer groupContainer = grouperRequestContainer.getGroupContainer();
1169
1170 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
1171 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
1172
1173 GrouperSession grouperSession = null;
1174
1175 try {
1176 grouperSession = GrouperSession.start(loggedInSubject);
1177
1178 String searchString = request.getParameter("addGroupSearch");
1179
1180 boolean searchOk = GrouperUiUtils.searchStringValid(searchString);
1181 if (!searchOk) {
1182
1183 guiResponseJs.addAction(GuiScreenAction.newInnerHtml("#addGroupResults",
1184 TextContainer.retrieveFromRequest().getText().get("groupImportAddToGroupNotEnoughChars")));
1185 return;
1186 }
1187
1188 String matchExactIdString = request.getParameter("matchExactId[]");
1189 boolean matchExactId = GrouperUtil.booleanValue(matchExactIdString, false);
1190
1191 GuiPaging guiPaging = groupContainer.getGuiPaging();
1192 QueryOptions queryOptions = new QueryOptions();
1193
1194 GrouperPagingTag2.processRequest(request, guiPaging, queryOptions);
1195
1196 Set<Group> groups = null;
1197
1198
1199 GroupFinder groupFinder = new GroupFinder().assignPrivileges(AccessPrivilege.UPDATE_PRIVILEGES)
1200 .assignScope(searchString).assignSplitScope(true).assignQueryOptions(queryOptions);
1201
1202 if (matchExactId) {
1203 groupFinder.assignFindByUuidOrName(true);
1204 }
1205
1206 groups = groupFinder.findGroups();
1207
1208 guiPaging.setTotalRecordCount(queryOptions.getQueryPaging().getTotalRecordCount());
1209
1210 if (GrouperUtil.length(groups) == 0) {
1211
1212 guiResponseJs.addAction(GuiScreenAction.newInnerHtml("#addGroupResults",
1213 TextContainer.retrieveFromRequest().getText().get("groupImportAddGroupNotFound")));
1214 return;
1215 }
1216
1217 Set<GuiGroup> guiGroups = GuiGroup.convertFromGroups(groups);
1218
1219 groupContainer.setGuiGroups(guiGroups);
1220
1221 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#addGroupResults",
1222 "/WEB-INF/grouperUi2/groupImport/groupImportAddGroupResults.jsp"));
1223
1224 } finally {
1225 GrouperSession.stopQuietly(grouperSession);
1226 }
1227
1228 }
1229
1230
1231
1232
1233
1234
1235
1236 public void groupImportRemoveGroup(HttpServletRequest request, HttpServletResponse response) {
1237
1238 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
1239
1240 GrouperSession grouperSession = null;
1241
1242 try {
1243
1244 grouperSession = GrouperSession.start(loggedInSubject);
1245
1246 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
1247
1248 groupImportSetupExtraGroups(loggedInSubject, request, guiResponseJs, true, false, new LinkedHashSet<Group>(), false);
1249
1250 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#groupImportExtraGroupsDivId",
1251 "/WEB-INF/grouperUi2/groupImport/groupImportExtraGroups.jsp"));
1252
1253 } finally {
1254 GrouperSession.stopQuietly(grouperSession);
1255 }
1256 }
1257
1258
1259
1260
1261
1262
1263 public void groupImportRemoveSubject(HttpServletRequest request, HttpServletResponse response) {
1264
1265 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
1266
1267 GrouperSession grouperSession = null;
1268
1269 try {
1270
1271 grouperSession = GrouperSession.start(loggedInSubject);
1272
1273 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
1274
1275 groupImportSetupExtraSubjects(loggedInSubject, request, guiResponseJs, true, false, new LinkedHashSet<Subject>(), false);
1276
1277 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#groupImportExtraMembersDivId",
1278 "/WEB-INF/grouperUi2/groupImport/groupImportExtraSubjects.jsp"));
1279
1280 } finally {
1281 GrouperSession.stopQuietly(grouperSession);
1282 }
1283 }
1284
1285
1286
1287
1288
1289
1290 public void groupImportAddGroup(HttpServletRequest request, HttpServletResponse response) {
1291
1292 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
1293
1294 GrouperSession grouperSession = null;
1295
1296 try {
1297
1298 grouperSession = GrouperSession.start(loggedInSubject);
1299
1300 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
1301
1302 groupImportSetupExtraGroups(loggedInSubject, request, guiResponseJs, false, true, new LinkedHashSet<Group>(), true);
1303
1304
1305 guiResponseJs.addAction(GuiScreenAction.newScript(
1306 "dijit.byId('groupImportGroupComboId').set('displayedValue', ''); " +
1307 "dijit.byId('groupImportGroupComboId').set('value', '');"));
1308
1309
1310 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#groupImportExtraGroupsDivId",
1311 "/WEB-INF/grouperUi2/groupImport/groupImportExtraGroups.jsp"));
1312
1313 } finally {
1314 GrouperSession.stopQuietly(grouperSession);
1315 }
1316 }
1317
1318
1319
1320
1321
1322
1323 public void groupImport(HttpServletRequest request, HttpServletResponse response) {
1324
1325 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
1326
1327 GrouperSession grouperSession = null;
1328
1329 try {
1330
1331 grouperSession = GrouperSession.start(loggedInSubject);
1332
1333 GrouperRequestContainerperRequestContainer.html#GrouperRequestContainer">GrouperRequestContainer grouperRequestContainer = new GrouperRequestContainer();
1334 GroupImportContainer groupImportContainer = grouperRequestContainer.getGroupImportContainer();
1335
1336 String backTo = request.getParameter("backTo");
1337
1338 {
1339
1340 Group group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.UPDATE, false).getGroup();
1341 if (group != null && StringUtils.equals("group", backTo)) {
1342 groupImportContainer.setImportFromGroup(true);
1343 }
1344 }
1345 {
1346 Subject subject = UiV2Subject.retrieveSubjectHelper(request, false);
1347 if (subject != null && StringUtils.equals("subject", backTo)) {
1348 groupImportContainer.setImportFromSubject(true);
1349 }
1350 }
1351
1352
1353 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
1354
1355 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId",
1356 "/WEB-INF/grouperUi2/groupImport/groupImport.jsp"));
1357
1358 } finally {
1359 GrouperSession.stopQuietly(grouperSession);
1360 }
1361 }
1362
1363
1364
1365
1366
1367
1368 public void groupImportAddMember(HttpServletRequest request, HttpServletResponse response) {
1369
1370 final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn();
1371
1372 GrouperSession grouperSession = null;
1373
1374 try {
1375
1376 grouperSession = GrouperSession.start(loggedInSubject);
1377
1378 GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs();
1379
1380 groupImportSetupExtraSubjects(loggedInSubject, request, guiResponseJs, false, true, new LinkedHashSet<Subject>(), true);
1381
1382
1383 guiResponseJs.addAction(GuiScreenAction.newScript(
1384 "dijit.byId('groupAddMemberComboId').set('displayedValue', ''); " +
1385 "dijit.byId('groupAddMemberComboId').set('value', '');"));
1386
1387
1388 guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#groupImportExtraMembersDivId",
1389 "/WEB-INF/grouperUi2/groupImport/groupImportExtraSubjects.jsp"));
1390
1391 } finally {
1392 GrouperSession.stopQuietly(grouperSession);
1393 }
1394 }
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406 private boolean groupImportSetupExtraSubjects(Subject loggedInSubject,
1407 HttpServletRequest request, GuiResponseJs guiResponseJs, boolean considerRemoveSubjectSourceAndId,
1408 boolean includeCombobox, Set<Subject> allSubjects, boolean errorOnNullCombobox) {
1409
1410
1411 Set<MultiKey> extraSubjectSourceAndIds = new HashSet<MultiKey>();
1412 Set<GuiSubject> extraGuiSubjects = new LinkedHashSet<GuiSubject>();
1413
1414 GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupImportContainer().setGroupImportExtraGuiSubjects(extraGuiSubjects);
1415
1416 Set<MultiKey> allSubjectsSourceAndIds = new HashSet<MultiKey>();
1417
1418 String removeSubjectSourceAndId = null;
1419
1420
1421 if (considerRemoveSubjectSourceAndId) {
1422 removeSubjectSourceAndId = request.getParameter("removeSubjectSourceAndId");
1423 if (StringUtils.isBlank(removeSubjectSourceAndId)) {
1424 throw new RuntimeException("Why would removeSubjectSourceAndId be empty????");
1425 }
1426 }
1427
1428 Subject theSubject = null;
1429
1430 {
1431
1432 String comboValue = request.getParameter("groupAddMemberComboName");
1433
1434 if (StringUtils.isBlank(comboValue)) {
1435
1436 comboValue = request.getParameter("groupAddMemberComboDisplay");
1437 }
1438
1439 try {
1440 GrouperSourceAdapter.searchForGroupsWithReadPrivilege(true);
1441 if (comboValue != null && comboValue.contains("||")) {
1442 String sourceId = GrouperUtil.prefixOrSuffix(comboValue, "||", true);
1443 String subjectId = GrouperUtil.prefixOrSuffix(comboValue, "||", false);
1444 theSubject = SubjectFinder.findByIdOrIdentifierAndSource(subjectId, sourceId, false);
1445 } else {
1446 try {
1447 theSubject = StringUtils.isBlank(comboValue) ? null : SubjectFinder.findByIdOrIdentifier(comboValue, false);
1448 } catch (SubjectNotUniqueException snue) {
1449
1450 }
1451 }
1452 } finally {
1453 GrouperSourceAdapter.clearSearchForGroupsWithReadPrivilege();
1454 }
1455 }
1456 boolean success = true;
1457 if (theSubject == null) {
1458 if (includeCombobox && errorOnNullCombobox) {
1459 guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error,
1460 "#groupAddMemberComboErrorId",
1461 TextContainer.retrieveFromRequest().getText().get("groupImportSubjectNotFound")));
1462 success = false;
1463 }
1464
1465 } else {
1466 MultiKey multiKey = new MultiKey(theSubject.getSourceId(), theSubject.getId());
1467 if (includeCombobox) {
1468 if (!extraSubjectSourceAndIds.contains(multiKey)) {
1469 extraGuiSubjects.add(new GuiSubject(theSubject));
1470 extraSubjectSourceAndIds.add(multiKey);
1471 }
1472 }
1473
1474 if (!allSubjectsSourceAndIds.contains(multiKey)) {
1475 allSubjects.add(theSubject);
1476 allSubjectsSourceAndIds.add(multiKey);
1477 }
1478 }
1479
1480
1481 for (int i=0;i<100;i++) {
1482 String extraSourceIdSubjectId = request.getParameter("extraSourceIdSubjectId_" + i);
1483
1484
1485 if (StringUtils.isBlank(extraSourceIdSubjectId)) {
1486 break;
1487 }
1488
1489
1490 if (considerRemoveSubjectSourceAndId && StringUtils.equals(removeSubjectSourceAndId, extraSourceIdSubjectId)) {
1491 continue;
1492 }
1493
1494 theSubject = null;
1495
1496 try {
1497 GrouperSourceAdapter.searchForGroupsWithReadPrivilege(true);
1498 if (extraSourceIdSubjectId != null && extraSourceIdSubjectId.contains("||")) {
1499 String sourceId = GrouperUtil.prefixOrSuffix(extraSourceIdSubjectId, "||", true);
1500 String subjectId = GrouperUtil.prefixOrSuffix(extraSourceIdSubjectId, "||", false);
1501 theSubject = SubjectFinder.findByIdOrIdentifierAndSource(subjectId, sourceId, false);
1502 }
1503 } finally {
1504 GrouperSourceAdapter.clearSearchForGroupsWithReadPrivilege();
1505 }
1506
1507 if (theSubject != null) {
1508 MultiKey multiKey = new MultiKey(theSubject.getSourceId(), theSubject.getId());
1509 if (!extraSubjectSourceAndIds.contains(multiKey)) {
1510 extraGuiSubjects.add(new GuiSubject(theSubject));
1511 extraSubjectSourceAndIds.add(multiKey);
1512 }
1513
1514 if (!allSubjectsSourceAndIds.contains(multiKey)) {
1515 allSubjects.add(theSubject);
1516 allSubjectsSourceAndIds.add(multiKey);
1517 }
1518 }
1519 }
1520 return success;
1521 }
1522
1523 }