Changeset 15010 in josm


Ignore:
Timestamp:
2019-04-21T17:55:22+02:00 (7 months ago)
Author:
Don-vip
Message:

fix #17634 - Reject uploads that do not follow comment/source upload policy, using the following 4 new properties:

  • upload.comment.forbidden-terms
  • upload.comment.mandatory-terms
  • upload.source.forbidden-terms
  • upload.source.mandatory-terms
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/io/UploadDialog.java

    r14977 r15010  
    1717import java.lang.Character.UnicodeBlock;
    1818import java.util.ArrayList;
     19import java.util.Arrays;
    1920import java.util.Collection;
    2021import java.util.Collections;
     
    2627import java.util.Optional;
    2728import java.util.concurrent.TimeUnit;
     29import java.util.stream.Collectors;
    2830
    2931import javax.swing.AbstractAction;
     
    490492        }
    491493
     494        /**
     495         * Displays a warning message indicating that the upload comment is rejected.
     496         * @param details details explaining why
     497         * @return {@code true}
     498         */
     499        protected boolean warnRejectedUploadComment(String details) {
     500            return warnRejectedUploadTag(
     501                    tr("Please revise upload comment"),
     502                    tr("Your upload comment is <i>rejected</i>.") + "<br />" + details
     503            );
     504        }
     505
     506        /**
     507         * Displays a warning message indicating that the changeset source is rejected.
     508         * @param details details explaining why
     509         * @return {@code true}
     510         */
     511        protected boolean warnRejectedUploadSource(String details) {
     512            return warnRejectedUploadTag(
     513                    tr("Please revise changeset source"),
     514                    tr("Your changeset source is <i>rejected</i>.") + "<br />" + details
     515            );
     516        }
     517
     518        /**
     519         * Warn about an upload tag with the possibility of resuming the upload.
     520         * @param title dialog title
     521         * @param message dialog message
     522         * @param togglePref preference entry to offer the user a "Do not show again" checkbox for the dialog
     523         * @return {@code true} if the user wants to revise the upload tag
     524         */
    492525        protected boolean warnUploadTag(final String title, final String message, final String togglePref) {
    493             String[] buttonTexts = new String[] {tr("Revise"), tr("Cancel"), tr("Continue as is")};
    494             Icon[] buttonIcons = new Icon[] {
     526            return warnUploadTag(title, message, togglePref, true);
     527        }
     528
     529        /**
     530         * Warn about an upload tag without the possibility of resuming the upload.
     531         * @param title dialog title
     532         * @param message dialog message
     533         * @return {@code true}
     534         */
     535        protected boolean warnRejectedUploadTag(final String title, final String message) {
     536            return warnUploadTag(title, message, null, false);
     537        }
     538
     539        private boolean warnUploadTag(final String title, final String message, final String togglePref, boolean allowContinue) {
     540            List<String> buttonTexts = new ArrayList<>(Arrays.asList(tr("Revise"), tr("Cancel")));
     541            List<Icon> buttonIcons = new ArrayList<>(Arrays.asList(
    495542                    new ImageProvider("ok").setMaxSize(ImageSizes.LARGEICON).get(),
    496                     new ImageProvider("cancel").setMaxSize(ImageSizes.LARGEICON).get(),
    497                     new ImageProvider("upload").setMaxSize(ImageSizes.LARGEICON).addOverlay(
    498                             new ImageOverlay(new ImageProvider("warning-small"), 0.5, 0.5, 1.0, 1.0)).get()};
    499             String[] tooltips = new String[] {
     543                    new ImageProvider("cancel").setMaxSize(ImageSizes.LARGEICON).get()));
     544            List<String> tooltips = new ArrayList<>(Arrays.asList(
    500545                    tr("Return to the previous dialog to enter a more descriptive comment"),
    501                     tr("Cancel and return to the previous dialog"),
    502                     tr("Ignore this hint and upload anyway")};
    503 
    504             ExtendedDialog dlg = new ExtendedDialog((Component) dialog, title, buttonTexts) {
     546                    tr("Cancel and return to the previous dialog")));
     547            if (allowContinue) {
     548                buttonTexts.add(tr("Continue as is"));
     549                buttonIcons.add(new ImageProvider("upload").setMaxSize(ImageSizes.LARGEICON).addOverlay(
     550                        new ImageOverlay(new ImageProvider("warning-small"), 0.5, 0.5, 1.0, 1.0)).get());
     551                tooltips.add(tr("Ignore this hint and upload anyway"));
     552            }
     553
     554            ExtendedDialog dlg = new ExtendedDialog((Component) dialog, title, buttonTexts.toArray(new String[] {})) {
    505555                @Override
    506556                public void setupDialog() {
     
    510560            };
    511561            dlg.setContent("<html>" + message + "</html>");
    512             dlg.setButtonIcons(buttonIcons);
    513             dlg.setToolTipTexts(tooltips);
     562            dlg.setButtonIcons(buttonIcons.toArray(new Icon[] {}));
     563            dlg.setToolTipTexts(tooltips.toArray(new String[] {}));
    514564            dlg.setIcon(JOptionPane.WARNING_MESSAGE);
    515             dlg.toggleEnable(togglePref);
     565            if (allowContinue) {
     566                dlg.toggleEnable(togglePref);
     567            }
    516568            dlg.setCancelButton(1, 2);
    517569            return dlg.showDialog().getValue() != 3;
     
    542594        }
    543595
     596        static String validateUploadTag(String uploadValue, String preferencePrefix) {
     597            // Check mandatory terms
     598            List<String> missingTerms = Config.getPref().getList(preferencePrefix+".mandatory-terms")
     599                .stream().filter(x -> !uploadValue.contains(x)).collect(Collectors.toList());
     600            if (!missingTerms.isEmpty()) {
     601                return tr("The following required terms are missing: {0}", missingTerms);
     602            }
     603            // Check forbidden terms
     604            List<String> forbiddenTerms = Config.getPref().getList(preferencePrefix+".forbidden-terms")
     605                    .stream().filter(uploadValue::contains).collect(Collectors.toList());
     606            if (!forbiddenTerms.isEmpty()) {
     607                return tr("The following forbidden terms have been found: {0}", forbiddenTerms);
     608            }
     609            return null;
     610        }
     611
    544612        @Override
    545613        public void actionPerformed(ActionEvent e) {
     
    547615            dialog.forceUpdateActiveField();
    548616
    549             if (isUploadCommentTooShort(dialog.getUploadComment()) && warnUploadComment()) {
    550                 // abort for missing comment
     617            final String uploadComment = dialog.getUploadComment();
     618            final String uploadCommentRejection = validateUploadTag(uploadComment, "upload.comment");
     619            if ((isUploadCommentTooShort(uploadComment) && warnUploadComment()) ||
     620                (uploadCommentRejection != null && warnRejectedUploadComment(uploadCommentRejection))) {
     621                // abort for missing or rejected comment
    551622                dialog.handleMissingComment();
    552623                return;
    553624            }
    554             if (dialog.getUploadSource().trim().isEmpty() && warnUploadSource()) {
    555                 // abort for missing changeset source
     625            final String uploadSource = dialog.getUploadSource();
     626            final String uploadSourceRejection = validateUploadTag(uploadSource, "upload.source");
     627            if ((Utils.isStripEmpty(uploadSource) && warnUploadSource()) ||
     628                    (uploadSourceRejection != null && warnRejectedUploadSource(uploadSourceRejection))) {
     629                // abort for missing or rejected changeset source
    556630                dialog.handleMissingSource();
    557631                return;
     
    562636            List<String> emptyChangesetTags = new ArrayList<>();
    563637            for (final Entry<String, String> i : dialog.getTags(true).entrySet()) {
    564                 final boolean isKeyEmpty = i.getKey() == null || i.getKey().trim().isEmpty();
    565                 final boolean isValueEmpty = i.getValue() == null || i.getValue().trim().isEmpty();
     638                final boolean isKeyEmpty = Utils.isStripEmpty(i.getKey());
     639                final boolean isValueEmpty = Utils.isStripEmpty(i.getValue());
    566640                final boolean ignoreKey = "comment".equals(i.getKey()) || "source".equals(i.getKey());
    567641                if ((isKeyEmpty ^ isValueEmpty) && !ignoreKey) {
     
    648722        if (evt.getPropertyName().equals(ChangesetManagementPanel.SELECTED_CHANGESET_PROP)) {
    649723            Changeset cs = (Changeset) evt.getNewValue();
    650             setChangesetTags(dataSet, cs == null); // keep comment/source of first tab for new changesets 
     724            setChangesetTags(dataSet, cs == null); // keep comment/source of first tab for new changesets
    651725            if (cs == null) {
    652726                tpConfigPanels.setTitleAt(1, tr("Tags of new changeset"));
  • trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogTest.java

    r14977 r15010  
    2121import org.openstreetmap.josm.TestUtils;
    2222import org.openstreetmap.josm.gui.ExtendedDialog;
     23import org.openstreetmap.josm.gui.io.UploadDialog.UploadAction;
    2324import org.openstreetmap.josm.io.UploadStrategySpecification;
    2425import org.openstreetmap.josm.spi.preferences.Config;
     
    258259                BasicUploadSettingsPanel.getDefaultSources().get(0));
    259260    }
     261
     262    private static void doTestValidateUploadTag(String prefix) {
     263        Config.getPref().putList(prefix + ".mandatory-terms", null);
     264        Config.getPref().putList(prefix + ".forbidden-terms", null);
     265        assertNull(UploadAction.validateUploadTag("foo", prefix));
     266
     267        Config.getPref().putList(prefix + ".mandatory-terms", Arrays.asList("foo"));
     268        assertNull(UploadAction.validateUploadTag("foo", prefix));
     269        assertEquals("The following required terms are missing: [foo]",
     270                UploadAction.validateUploadTag("bar", prefix));
     271
     272        Config.getPref().putList(prefix + ".forbidden-terms", Arrays.asList("bar"));
     273        assertNull(UploadAction.validateUploadTag("foo", prefix));
     274        assertEquals("The following forbidden terms have been found: [bar]",
     275                UploadAction.validateUploadTag("foobar", prefix));
     276    }
     277
     278    /**
     279     * Test of {@link UploadDialog.UploadAction#validateUploadTag} method.
     280     */
     281    @Test
     282    public void testvalidateUploadTag() {
     283        doTestValidateUploadTag("upload.comment");
     284        doTestValidateUploadTag("upload.source");
     285    }
    260286}
Note: See TracChangeset for help on using the changeset viewer.