001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.ui; 018 019import static org.opends.messages.AdminToolMessages.*; 020import static com.forgerock.opendj.cli.Utils.isDN; 021 022import java.awt.Component; 023import java.awt.GridBagConstraints; 024import java.awt.GridBagLayout; 025import java.util.ArrayList; 026import java.util.Collection; 027 028import javax.swing.JLabel; 029import javax.swing.JPanel; 030import javax.swing.JScrollPane; 031import javax.swing.JTextArea; 032import javax.swing.JTextField; 033import javax.swing.event.ChangeEvent; 034import javax.swing.event.ChangeListener; 035import javax.swing.text.JTextComponent; 036 037import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; 038import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor; 039import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 040import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; 041import org.opends.guitools.controlpanel.task.Task; 042import org.opends.guitools.controlpanel.ui.components.BasicExpander; 043import org.opends.guitools.controlpanel.util.Utilities; 044import org.forgerock.i18n.LocalizableMessage; 045import org.opends.server.protocols.ldap.LDAPFilter; 046import org.forgerock.opendj.ldap.DN; 047import org.opends.server.types.LDAPException; 048 049/** 050 * Abstract class used to refactor some code used by the import LDIF and export 051 * LDIF panels. 052 * 053 */ 054public abstract class InclusionExclusionPanel extends StatusGenericPanel 055{ 056 private static final long serialVersionUID = -3826176895778069011L; 057 /** 058 * The DNs to exclude. 059 */ 060 protected JTextArea dnsToExclude; 061 /** 062 * The attributes to exclude. 063 */ 064 protected JTextField attributesToExclude; 065 /** 066 * The exclusion filter. 067 */ 068 protected JTextField exclusionFilter; 069 /** 070 * The DNs to include. 071 */ 072 protected JTextArea dnsToInclude; 073 /** 074 * The attributes to include. 075 */ 076 protected JTextField attributesToInclude; 077 /** 078 * The inclusion filter. 079 */ 080 protected JTextField inclusionFilter; 081 082 /** 083 * The DNs to include. 084 */ 085 protected JLabel lDnsToInclude; 086 /** 087 * The attributes to include. 088 */ 089 protected JLabel lAttributesToInclude; 090 /** 091 * The inclusion filter label. 092 */ 093 protected JLabel lInclusionFilter; 094 /** 095 * The DNs to exclude label. 096 */ 097 protected JLabel lDnsToExclude; 098 /** 099 * The attributes to exclude label. 100 */ 101 protected JLabel lAttributesToExclude; 102 /** 103 * The exclusion filter label. 104 */ 105 protected JLabel lExclusionFilter; 106 107 /** {@inheritDoc} */ 108 public void cancelClicked() 109 { 110 setPrimaryValid(lDnsToInclude); 111 setPrimaryValid(lAttributesToInclude); 112 setPrimaryValid(lInclusionFilter); 113 setPrimaryValid(lDnsToExclude); 114 setPrimaryValid(lAttributesToExclude); 115 setPrimaryValid(lExclusionFilter); 116 super.cancelClicked(); 117 } 118 119 /** 120 * A commodity method that layouts a set of components. 121 * @param extraComponentLabels the labels. 122 * @param extraComponents the components. 123 * @return the panel containing the labels and the components. 124 */ 125 protected Component createDataInclusionOptions( 126 final JLabel[] extraComponentLabels, 127 final Component[] extraComponents) 128 { 129 JPanel panel = new JPanel(new GridBagLayout()); 130 panel.setOpaque(false); 131 GridBagConstraints gbc = new GridBagConstraints(); 132 gbc.weightx = 1.0; 133 gbc.gridwidth = 2; 134 gbc.gridx = 0; 135 gbc.gridy = 0; 136 gbc.anchor = GridBagConstraints.NORTHWEST; 137 gbc.fill = GridBagConstraints.HORIZONTAL; 138 int labelInsetLeft = 15; 139 final BasicExpander expander = 140 new BasicExpander(INFO_CTRL_PANEL_DATA_INCLUSION_OPTIONS.get()); 141 panel.add(expander, gbc); 142 143 gbc.gridy ++; 144 lDnsToInclude = 145 Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DNS_TO_INCLUDE.get()); 146 gbc.insets.left = labelInsetLeft; 147 gbc.anchor = GridBagConstraints.NORTHWEST; 148 gbc.insets.top = 10; 149 gbc.gridwidth = 1; 150 gbc.weightx = 0.0; 151 panel.add(lDnsToInclude, gbc); 152 153 gbc.gridx = 1; 154 gbc.weightx = 1.0; 155 gbc.insets.left = 10; 156 dnsToInclude = Utilities.createTextArea(LocalizableMessage.EMPTY, 5, 25); 157 final JScrollPane scrollDns = Utilities.createScrollPane(dnsToInclude); 158 panel.add(scrollDns, gbc); 159 lDnsToInclude.setLabelFor(dnsToInclude); 160 161 gbc.insets.top = 2; 162 gbc.gridy ++; 163 final JLabel lDnsExplanation = Utilities.createInlineHelpLabel( 164 INFO_CTRL_PANEL_SEPARATE_DNS_LINE_BREAK.get()); 165 panel.add(lDnsExplanation, gbc); 166 167 gbc.gridy ++; 168 gbc.gridx = 0; 169 gbc.weightx = 0.0; 170 lAttributesToInclude = Utilities.createPrimaryLabel( 171 INFO_CTRL_PANEL_ATTRIBUTES_TO_INCLUDE.get()); 172 gbc.insets.left = labelInsetLeft; 173 gbc.anchor = GridBagConstraints.NORTHWEST; 174 gbc.insets.top = 10; 175 gbc.gridwidth = 1; 176 panel.add(lAttributesToInclude, gbc); 177 178 gbc.gridx = 1; 179 gbc.weightx = 1.0; 180 gbc.insets.left = 10; 181 gbc.weightx = 1.0; 182 attributesToInclude = Utilities.createMediumTextField(); 183 panel.add(attributesToInclude, gbc); 184 lAttributesToInclude.setLabelFor(attributesToInclude); 185 186 gbc.insets.top = 2; 187 gbc.gridy ++; 188 final JLabel lAttributesExplanation = Utilities.createInlineHelpLabel( 189 INFO_CTRL_PANEL_SEPARATE_ATTRIBUTES_COMMA.get()); 190 panel.add(lAttributesExplanation, gbc); 191 192 gbc.gridy ++; 193 gbc.gridx = 0; 194 lInclusionFilter = Utilities.createPrimaryLabel( 195 INFO_CTRL_PANEL_INCLUSION_FILTER.get()); 196 gbc.insets.left = labelInsetLeft; 197 gbc.anchor = GridBagConstraints.NORTHWEST; 198 gbc.insets.top = 10; 199 gbc.gridwidth = 1; 200 gbc.weightx = 0.0; 201 panel.add(lInclusionFilter, gbc); 202 203 gbc.gridx = 1; 204 gbc.weightx = 1.0; 205 gbc.insets.left = 10; 206 inclusionFilter = Utilities.createMediumTextField(); 207 panel.add(inclusionFilter, gbc); 208 lInclusionFilter.setLabelFor(inclusionFilter); 209 210 addExtraComponents(panel, extraComponentLabels, extraComponents, gbc, 211 labelInsetLeft); 212 213 ChangeListener changeListener = new ChangeListener() 214 { 215 /** {@inheritDoc} */ 216 public void stateChanged(ChangeEvent e) 217 { 218 lDnsToInclude.setVisible(expander.isSelected()); 219 scrollDns.setVisible(expander.isSelected()); 220 lDnsExplanation.setVisible(expander.isSelected()); 221 lAttributesToInclude.setVisible(expander.isSelected()); 222 attributesToInclude.setVisible(expander.isSelected()); 223 lAttributesExplanation.setVisible(expander.isSelected()); 224 lInclusionFilter.setVisible(expander.isSelected()); 225 inclusionFilter.setVisible(expander.isSelected()); 226 expanderStateChanged(expander, extraComponentLabels, extraComponents); 227 } 228 }; 229 expander.addChangeListener(changeListener); 230 expander.setSelected(false); 231 changeListener.stateChanged(null); 232 233 return panel; 234 } 235 236 /** 237 * A commodity method that layouts a set of components. 238 * @param extraComponentLabels the labels. 239 * @param extraComponents the components. 240 * @return the panel containing the labels and the components. 241 */ 242 protected Component createDataExclusionOptions( 243 final JLabel[] extraComponentLabels, 244 final Component[] extraComponents) 245 { 246 JPanel panel = new JPanel(new GridBagLayout()); 247 panel.setOpaque(false); 248 GridBagConstraints gbc = new GridBagConstraints(); 249 gbc.weightx = 1.0; 250 gbc.gridwidth = 2; 251 gbc.gridx = 0; 252 gbc.gridy = 0; 253 gbc.anchor = GridBagConstraints.NORTHWEST; 254 gbc.fill = GridBagConstraints.HORIZONTAL; 255 int labelInsetLeft = 15; 256 final BasicExpander expander = 257 new BasicExpander(INFO_CTRL_PANEL_DATA_EXCLUSION_OPTIONS.get()); 258 panel.add(expander, gbc); 259 260 gbc.gridy ++; 261 lDnsToExclude = 262 Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DNS_TO_EXCLUDE.get()); 263 gbc.insets.left = labelInsetLeft; 264 gbc.anchor = GridBagConstraints.NORTHWEST; 265 gbc.insets.top = 10; 266 gbc.gridwidth = 1; 267 gbc.weightx = 0.0; 268 panel.add(lDnsToExclude, gbc); 269 270 gbc.gridx = 1; 271 gbc.weightx = 1.0; 272 gbc.insets.left = 10; 273 dnsToExclude = Utilities.createTextArea(LocalizableMessage.EMPTY, 5, 0); 274 final JScrollPane scrollDns = Utilities.createScrollPane(dnsToExclude); 275 lDnsToExclude.setLabelFor(dnsToExclude); 276 panel.add(scrollDns, gbc); 277 278 gbc.insets.top = 2; 279 gbc.gridy ++; 280 final JLabel lDnsExplanation = Utilities.createInlineHelpLabel( 281 INFO_CTRL_PANEL_SEPARATE_DNS_LINE_BREAK.get()); 282 panel.add(lDnsExplanation, gbc); 283 284 gbc.gridy ++; 285 gbc.gridx = 0; 286 gbc.weightx = 0.0; 287 lAttributesToExclude = Utilities.createPrimaryLabel( 288 INFO_CTRL_PANEL_ATTRIBUTES_TO_EXCLUDE.get()); 289 gbc.insets.left = labelInsetLeft; 290 gbc.anchor = GridBagConstraints.NORTHWEST; 291 gbc.insets.top = 10; 292 gbc.gridwidth = 1; 293 panel.add(lAttributesToExclude, gbc); 294 295 gbc.gridx = 1; 296 gbc.weightx = 1.0; 297 gbc.insets.left = 10; 298 gbc.weightx = 1.0; 299 attributesToExclude = Utilities.createTextField(); 300 panel.add(attributesToExclude, gbc); 301 lAttributesToExclude.setLabelFor(dnsToExclude); 302 303 gbc.insets.top = 2; 304 gbc.gridy ++; 305 final JLabel lAttributesExplanation = Utilities.createInlineHelpLabel( 306 INFO_CTRL_PANEL_SEPARATE_ATTRIBUTES_COMMA.get()); 307 panel.add(lAttributesExplanation, gbc); 308 lAttributesExplanation.setLabelFor(dnsToExclude); 309 310 gbc.gridy ++; 311 gbc.gridx = 0; 312 lExclusionFilter = Utilities.createPrimaryLabel( 313 INFO_CTRL_PANEL_EXCLUSION_FILTER.get()); 314 gbc.insets.left = labelInsetLeft; 315 gbc.anchor = GridBagConstraints.NORTHWEST; 316 gbc.insets.top = 10; 317 gbc.gridwidth = 1; 318 gbc.weightx = 0.0; 319 panel.add(lExclusionFilter, gbc); 320 321 gbc.gridx = 1; 322 gbc.weightx = 1.0; 323 gbc.insets.left = 10; 324 exclusionFilter = Utilities.createTextField(); 325 panel.add(exclusionFilter, gbc); 326 lExclusionFilter.setLabelFor(exclusionFilter); 327 328 addExtraComponents(panel, extraComponentLabels, extraComponents, gbc, 329 labelInsetLeft); 330 331 ChangeListener changeListener = new ChangeListener() 332 { 333 /** {@inheritDoc} */ 334 public void stateChanged(ChangeEvent e) 335 { 336 lDnsToExclude.setVisible(expander.isSelected()); 337 scrollDns.setVisible(expander.isSelected()); 338 lDnsExplanation.setVisible(expander.isSelected()); 339 lAttributesToExclude.setVisible(expander.isSelected()); 340 attributesToExclude.setVisible(expander.isSelected()); 341 lAttributesExplanation.setVisible(expander.isSelected()); 342 lExclusionFilter.setVisible(expander.isSelected()); 343 exclusionFilter.setVisible(expander.isSelected()); 344 expanderStateChanged(expander, extraComponentLabels, extraComponents); 345 } 346 }; 347 expander.addChangeListener(changeListener); 348 expander.setSelected(false); 349 changeListener.stateChanged(null); 350 351 return panel; 352 } 353 354 private void addExtraComponents(JPanel panel, JLabel[] extraComponentLabels, 355 Component[] extraComponents, GridBagConstraints gbc, int labelInsetLeft) 356 { 357 for (int i=0; i<extraComponentLabels.length; i++) 358 { 359 gbc.gridy ++; 360 gbc.gridx = 0; 361 gbc.insets.left = labelInsetLeft; 362 gbc.anchor = GridBagConstraints.NORTHWEST; 363 gbc.insets.top = 10; 364 365 if (extraComponentLabels[i] == null) 366 { 367 gbc.gridwidth = 2; 368 gbc.weightx = 1.0; 369 panel.add(extraComponents[i], gbc); 370 } 371 else 372 { 373 gbc.gridwidth = 1; 374 gbc.weightx = 0.0; 375 panel.add(extraComponentLabels[i], gbc); 376 377 gbc.gridx = 1; 378 gbc.weightx = 1.0; 379 gbc.insets.left = 10; 380 panel.add(extraComponents[i], gbc); 381 382 extraComponentLabels[i].setLabelFor(extraComponents[i]); 383 } 384 } 385 } 386 387 private void expanderStateChanged(BasicExpander expander, 388 JLabel[] extraComponentLabels, 389 Component[] extraComponents) 390 { 391 for (JLabel comp : extraComponentLabels) 392 { 393 if (comp != null) 394 { 395 comp.setVisible(expander.isSelected()); 396 } 397 } 398 for (Component comp : extraComponents) 399 { 400 comp.setVisible(expander.isSelected()); 401 } 402 } 403 404 405 /** 406 * Updates a list of errors in the include and exclude subpanels. 407 * @param errors the list of errors to be updated. 408 * @param backendName the name of the backend where the operation associated 409 * with the panel applies (used to generate the error messages). 410 */ 411 protected void updateIncludeExclude(Collection<LocalizableMessage> errors, 412 String backendName) 413 { 414 updateErrors(lDnsToInclude, dnsToInclude, lAttributesToInclude, 415 attributesToInclude, lInclusionFilter, inclusionFilter, errors, 416 backendName); 417 updateErrors(lDnsToExclude, dnsToExclude, lAttributesToExclude, 418 attributesToExclude, lExclusionFilter, exclusionFilter, errors, 419 backendName); 420 } 421 422 423 private void updateErrors(JLabel lDns, JTextComponent dns, JLabel lAttributes, 424 JTextComponent attributes, JLabel lFilter, JTextComponent filter, 425 Collection<LocalizableMessage> errors, String backendName) 426 { 427 setPrimaryValid(lDns); 428 setPrimaryValid(lAttributes); 429 setPrimaryValid(lFilter); 430 431 String s = dns.getText(); 432 433 boolean validDn = true; 434 435 if (s.trim().length() > 0) 436 { 437 String[] dnArray = s.split("\n"); 438 for (int i=0; i<dnArray.length; i++) 439 { 440 if (!isDN(dnArray[i])) 441 { 442 errors.add(ERR_CTRL_PANEL_DN_NOT_VALID_WITH_VALUE.get(dnArray[i])); 443 validDn = false; 444 } 445 else 446 { 447 BackendDescriptor backend = null; 448 449 if (backendName != null) 450 { 451 ServerDescriptor server = getInfo().getServerDescriptor(); 452 for (BackendDescriptor b : server.getBackends()) 453 { 454 if (b.getBackendID().equalsIgnoreCase(backendName)) 455 { 456 backend = b; 457 break; 458 } 459 } 460 } 461 462 if (backend != null) 463 { 464 boolean found = false; 465 for (BaseDNDescriptor baseDN : backend.getBaseDns()) 466 { 467 try 468 { 469 DN dn = DN.valueOf(dnArray[i]); 470 if (dn.isSubordinateOrEqualTo(baseDN.getDn())) 471 { 472 found = true; 473 break; 474 } 475 } 476 catch (Throwable t) 477 { 478 // Bug 479 t.printStackTrace(); 480 } 481 } 482 if (!found) 483 { 484 errors.add(ERR_CTRL_PANEL_NOT_A_DESCENDANT_OF_BASE_DN.get( 485 dnArray[i], backendName)); 486 } 487 } 488 } 489 } 490 } 491 492 if (!validDn) 493 { 494 setPrimaryInvalid(lDns); 495 } 496 497 s = attributes.getText(); 498 499 boolean validAttributes = true; 500 501 if (s.trim().length() > 0) 502 { 503 String[] attributeArray = s.split(","); 504 for (int i=0; i<attributeArray.length; i++) 505 { 506 if (!Utilities.isValidAttributeName(attributeArray[i])) 507 { 508 errors.add(ERR_CTRL_PANEL_NOT_VALID_ATTRIBUTE_NAME.get( 509 attributeArray[i])); 510 validAttributes = false; 511 } 512 } 513 } 514 515 if (!validAttributes) 516 { 517 setPrimaryInvalid(lAttributes); 518 } 519 520 s = filter.getText(); 521 if (s != null && s.trim().length() > 0) 522 { 523 try 524 { 525 LDAPFilter.decode(s); 526 } 527 catch (LDAPException le) 528 { 529 errors.add(ERR_CTRL_PANEL_INVALID_FILTER_DETAILS_WITH_VALUE.get(s, le.getMessageObject())); 530 setPrimaryInvalid(lFilter); 531 } 532 } 533 } 534 535 /** 536 * Abstract class that provides some methods that can be used to generate the 537 * equivalent command-line arguments for some of the things that are contained 538 * in the inclusion/exclusion panels. 539 * 540 */ 541 protected abstract class InclusionExclusionTask extends Task 542 { 543 /** 544 * The constructor of the task. 545 * @param info the control panel info. 546 * @param dlg the progress dialog that shows the progress of the task. 547 */ 548 protected InclusionExclusionTask(ControlPanelInfo info, ProgressDialog dlg) 549 { 550 super(info, dlg); 551 } 552 553 /** 554 * Returns the command line arguments corresponding to the elements 555 * displayed in the inclusion/exclusion panels. 556 * @return the command line arguments corresponding to the elements 557 * displayed in the inclusion/exclusion panels. 558 */ 559 protected ArrayList<String> getCommandLineArguments() 560 { 561 ArrayList<String> args = new ArrayList<>(); 562 String s = dnsToInclude.getText(); 563 if (s.trim().length() > 0) 564 { 565 String[] dnArray = s.split("\n"); 566 for (int i=0; i<dnArray.length; i++) 567 { 568 args.add("--includeBranch"); 569 args.add(dnArray[i]); 570 } 571 } 572 s = attributesToInclude.getText(); 573 if (s.trim().length() > 0) 574 { 575 String[] attrArray = s.split(","); 576 for (int i=0; i<attrArray.length; i++) 577 { 578 args.add("--includeAttribute"); 579 args.add(attrArray[i]); 580 } 581 } 582 s = inclusionFilter.getText(); 583 if (s.trim().length() > 0) 584 { 585 args.add("--includeFilter"); 586 args.add(s); 587 } 588 589 s = dnsToExclude.getText(); 590 if (s.trim().length() > 0) 591 { 592 String[] dnArray = s.split("\n"); 593 for (int i=0; i<dnArray.length; i++) 594 { 595 args.add("--excludeBranch"); 596 args.add(dnArray[i]); 597 } 598 } 599 s = attributesToExclude.getText(); 600 if (s.trim().length() > 0) 601 { 602 String[] attrArray = s.split(","); 603 for (int i=0; i<attrArray.length; i++) 604 { 605 args.add("--excludeAttribute"); 606 args.add(attrArray[i]); 607 } 608 } 609 s = exclusionFilter.getText(); 610 if (s.trim().length() > 0) 611 { 612 args.add("--excludeFilter"); 613 args.add(s); 614 } 615 args.addAll(getConnectionCommandLineArguments()); 616 return args; 617 } 618 } 619}