001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.widgets;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.util.ArrayList;
007    import java.util.List;
008    import java.util.StringTokenizer;
009    
010    import javax.swing.JTextField;
011    import javax.swing.text.JTextComponent;
012    
013    import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
014    import org.openstreetmap.josm.data.osm.PrimitiveId;
015    import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
016    import org.openstreetmap.josm.tools.Utils;
017    
018    /**
019     * @author Matthias Julius
020     */
021    public class OsmIdTextField extends JTextField {
022    
023        private OsmIdValidator validator;
024    
025        public OsmIdTextField() {
026            validator = OsmIdValidator.decorate(this);
027        }
028    
029        public void setType(OsmPrimitiveType type) {
030            validator.type = type;
031        }
032    
033        /**
034         * Get entered ID list - supports "1,2,3" "1 2   ,3" or even "1 2 3 v2 6 v8"
035         * @return list of id's
036         */
037        public List<PrimitiveId> getIds() {
038            return validator.ids;
039        }
040    
041        public boolean readOsmIds() {
042            return validator.readOsmIds();
043        }
044    
045        public void performValidation() {
046            validator.validate();
047        }
048    
049        public void clearTextIfInvalid() {
050            if (!validator.isValid()) 
051                setText("");
052            validator.validate();
053        }
054    
055        /**
056         * Validator for a changeset ID entered in a {@link JTextComponent}.
057         *
058         */
059        static private class OsmIdValidator extends AbstractTextComponentValidator {
060    
061            static public OsmIdValidator decorate(JTextComponent tc) {
062                return new OsmIdValidator(tc);
063            }
064    
065            private List<PrimitiveId> ids = new ArrayList<PrimitiveId>();
066            private OsmPrimitiveType type;
067    
068            public OsmIdValidator(JTextComponent tc) {
069                super(tc, false);
070            }
071    
072            @Override
073            public boolean isValid() {
074                return readOsmIds();
075            }
076    
077            @Override
078            public void validate() {
079                if (!isValid()) {
080                    feedbackInvalid(tr("The current value is not a valid OSM ID. Please enter an integer value > 0"));
081                } else {
082                    feedbackValid(tr("Please enter an integer value > 0"));
083                }
084            }
085    
086            public boolean readOsmIds() {
087                String value = getComponent().getText();
088                char c;
089                if (value == null || value.trim().length() == 0) {
090                    return false;
091                }
092                ids.clear();
093                StringTokenizer st = new StringTokenizer(value, ",.+/ \t\n");
094                String s;
095                while (st.hasMoreTokens()) {
096                    s = st.nextToken();
097                    // convert tokens to int skipping v-words (version v2 etc)
098                    c = s.charAt(0);
099                    if (c == 'v') {
100                        continue;
101                    } else {
102                        try {
103                            ids.add(SimplePrimitiveId.fromString(s));
104                        } catch (IllegalArgumentException ex) {
105                            try {
106                                if (type == OsmPrimitiveType.NODE) {
107                                    ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.NODE));
108                                } else if (type == OsmPrimitiveType.WAY) {
109                                    ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.WAY));
110                                } else if (type == OsmPrimitiveType.RELATION) {
111                                    ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.RELATION));
112                                } else {
113                                    return false;
114                                }
115                            } catch (IllegalArgumentException ex2) {
116                                return false;
117                            }
118                        }
119                    }
120                }
121                return true;
122            }
123        }
124    }