Ticket #17459: plugin-remove-corehacks.patch

File plugin-remove-corehacks.patch, 36.8 KB (added by GerdP, 5 years ago)

patch for reverter plugin

  • build.xml

     
    33    <!-- enter the SVN commit message -->
    44    <property name="commit.message" value="Reverter: Update MultiOsmReader to support null data after redaction"/>
    55    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    6     <property name="plugin.main.version" value="14153"/>
     6    <property name="plugin.main.version" value="xxx"/>
    77
    88    <!-- Configure these properties (replace "..." accordingly).
    99         See https://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins
  • src/reverter/ChangesetReverter.java

     
    1717import org.openstreetmap.josm.data.conflict.Conflict;
    1818import org.openstreetmap.josm.data.coor.LatLon;
    1919import org.openstreetmap.josm.data.osm.Changeset;
     20import org.openstreetmap.josm.data.osm.ChangesetDataSet;
     21import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetDataSetEntry;
     22import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetModificationType;
    2023import org.openstreetmap.josm.data.osm.DataSet;
    2124import org.openstreetmap.josm.data.osm.Node;
    2225import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    2326import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    2427import org.openstreetmap.josm.data.osm.PrimitiveId;
    2528import org.openstreetmap.josm.data.osm.Relation;
    26 import org.openstreetmap.josm.data.osm.RelationMember;
    2729import org.openstreetmap.josm.data.osm.RelationMemberData;
    2830import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
    2931import org.openstreetmap.josm.data.osm.Way;
     
    3739import org.openstreetmap.josm.gui.util.GuiHelper;
    3840import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
    3941import org.openstreetmap.josm.io.OsmApiException;
     42import org.openstreetmap.josm.io.OsmServerChangesetReader;
    4043import org.openstreetmap.josm.io.OsmTransferException;
    4144import org.openstreetmap.josm.tools.Logging;
    4245import org.openstreetmap.josm.tools.Utils;
    4346
    44 import reverter.corehacks.ChangesetDataSet;
    45 import reverter.corehacks.ChangesetDataSet.ChangesetDataSetEntry;
    46 import reverter.corehacks.ChangesetDataSet.ChangesetModificationType;
    47 import reverter.corehacks.OsmServerChangesetReader;
    48 
    4947/**
    5048 * Fetches and stores data for reverting of specific changeset.
    5149 * @author Upliner
     
    147145        }
    148146        this.revertType = revertType;
    149147
    150         OsmServerChangesetReader csr = new OsmServerChangesetReader();
     148        OsmServerChangesetReader csr = new OsmServerChangesetReader(true, true);
    151149        monitor.beginTask("", 2);
    152         changeset = csr.readChangeset(changesetId, monitor.createSubTaskMonitor(1, false));
     150        changeset = csr.readChangeset(changesetId, false, monitor.createSubTaskMonitor(1, false));
    153151        if (MODERATOR_REDACTION_ACCOUNTS.contains(changeset.getUser().getId())) {
    154152            throw new RevertRedactedChangesetException(tr("It is not allowed to revert changeset from {0}", changeset.getUser().getName()));
    155153        }
     
    225223            for (HashSet<HistoryOsmPrimitive> collection : Arrays.asList(updated, deleted)) {
    226224                for (HistoryOsmPrimitive entry : collection) {
    227225                    PrimitiveId id = entry.getPrimitiveId();
    228                     readObjectVersion(rdr, id, cds.getEarliestVersion(id)-1, progressMonitor);
     226                    HistoryOsmPrimitive csPrimitive = cds.getPrimitive(id);
     227                    if (csPrimitive == null || csPrimitive.getVersion() == 1)
     228                        throw new OsmTransferException(tr("Unexpected data in changeset {1}" , changesetId));
     229                                        readObjectVersion(rdr, id, (int) cds.getPrimitive(id).getVersion() - 1, progressMonitor);
    229230                    if (progressMonitor.isCanceled()) return;
    230231                }
    231232            }
  • src/reverter/corehacks/ChangesetDataSet.java

     
    1 // License: GPL. For details, see LICENSE file.
    2 package reverter.corehacks;
    3 
    4 import java.util.HashMap;
    5 import java.util.HashSet;
    6 import java.util.Iterator;
    7 import java.util.Map;
    8 import java.util.Map.Entry;
    9 import java.util.Set;
    10 
    11 import org.openstreetmap.josm.data.osm.PrimitiveId;
    12 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
    13 import org.openstreetmap.josm.tools.CheckParameterUtil;
    14 
    15 /**
    16  * A ChangesetDataSet holds the content of a changeset.
    17  */
    18 public class ChangesetDataSet {
    19 
    20     public enum ChangesetModificationType {
    21         CREATED,
    22         UPDATED,
    23         DELETED
    24     }
    25 
    26     public interface ChangesetDataSetEntry {
    27         ChangesetModificationType getModificationType();
    28 
    29         HistoryOsmPrimitive getPrimitive();
    30 
    31         int getEarliestVersion();
    32     }
    33 
    34     private final Map<PrimitiveId, Integer> earliestVersions = new HashMap<>();
    35     private final Map<PrimitiveId, HistoryOsmPrimitive> primitives = new HashMap<>();
    36     private final Map<PrimitiveId, ChangesetModificationType> modificationTypes = new HashMap<>();
    37 
    38     /**
    39      * Remembers a history primitive with the given modification type
    40      *
    41      * @param primitive the primitive. Must not be null.
    42      * @param cmt the modification type. Must not be null.
    43      * @throws IllegalArgumentException thrown if primitive is null
    44      * @throws IllegalArgumentException thrown if cmt is null
    45      */
    46     public void put(HistoryOsmPrimitive primitive, ChangesetModificationType cmt) throws IllegalArgumentException {
    47         CheckParameterUtil.ensureParameterNotNull(primitive, "primitive");
    48         CheckParameterUtil.ensureParameterNotNull(cmt, "cmt");
    49         PrimitiveId pid = primitive.getPrimitiveId();
    50         if (primitives.containsKey(pid)) {
    51             // Save only latest versions of primitives for reverter
    52             if (primitive.getVersion() < primitives.get(pid).getVersion()) {
    53                 Integer earliest = earliestVersions.get(pid);
    54                 if (earliest == null || primitive.getVersion() < earliest) {
    55                     earliestVersions.put(pid, (int) primitive.getVersion());
    56                     if (cmt == ChangesetModificationType.CREATED)
    57                         modificationTypes.put(pid, cmt);
    58                 }
    59                 return;
    60             } else {
    61                 if (modificationTypes.get(pid) == ChangesetModificationType.CREATED) {
    62                     cmt = ChangesetModificationType.CREATED;
    63                 }
    64                 if (earliestVersions.get(pid) == null) {
    65                     earliestVersions.put(pid, (int) primitives.get(pid).getVersion());
    66                 }
    67             }
    68         }
    69         primitives.put(pid, primitive);
    70         modificationTypes.put(pid, cmt);
    71     }
    72 
    73     /**
    74      * Replies true if the changeset content contains the object with primitive <code>id</code>.
    75      * @param id the id.
    76      * @return true if the changeset content contains the object with primitive <code>id</code>
    77      */
    78     public boolean contains(PrimitiveId id) {
    79         if (id == null) return false;
    80         return primitives.containsKey(id);
    81     }
    82 
    83     /**
    84      * Replies the modification type for the object with id <code>id</code>. Replies null, if id is null or
    85      * if the object with id <code>id</code> isn't in the changeset content.
    86      *
    87      * @param id the id
    88      * @return the modification type
    89      */
    90     public ChangesetModificationType getModificationType(PrimitiveId id) {
    91         if (!contains(id)) return null;
    92         return modificationTypes.get(id);
    93     }
    94 
    95     public int getEarliestVersion(PrimitiveId id) {
    96         Integer earliestVersion = earliestVersions.get(id);
    97         if (earliestVersion == null) earliestVersion = (int) primitives.get(id).getVersion();
    98         return earliestVersion;
    99     }
    100 
    101     /**
    102      * Replies true if the primitive with id <code>id</code> was created in this
    103      * changeset. Replies false, if id is null.
    104      *
    105      * @param id the id
    106      * @return true if the primitive with id <code>id</code> was created in this
    107      * changeset.
    108      */
    109     public boolean isCreated(PrimitiveId id) {
    110         if (!contains(id)) return false;
    111         return ChangesetModificationType.CREATED.equals(getModificationType(id));
    112     }
    113 
    114     /**
    115      * Replies true if the primitive with id <code>id</code> was updated in this
    116      * changeset. Replies false, if id is null.
    117      *
    118      * @param id the id
    119      * @return true if the primitive with id <code>id</code> was updated in this
    120      * changeset.
    121      */
    122     public boolean isUpdated(PrimitiveId id) {
    123         if (!contains(id)) return false;
    124         return ChangesetModificationType.UPDATED.equals(getModificationType(id));
    125     }
    126 
    127     /**
    128      * Replies true if the primitive with id <code>id</code> was deleted in this
    129      * changeset. Replies false, if id is null.
    130      *
    131      * @param id the id
    132      * @return true if the primitive with id <code>id</code> was deleted in this
    133      * changeset.
    134      */
    135     public boolean isDeleted(PrimitiveId id) {
    136         if (!contains(id)) return false;
    137         return ChangesetModificationType.DELETED.equals(getModificationType(id));
    138     }
    139 
    140     /**
    141      * Replies the set of primitives with a specific modification type
    142      *
    143      * @param cmt the modification type. Must not be null.
    144      * @return the set of primitives
    145      * @throws IllegalArgumentException thrown if cmt is null
    146      */
    147     public Set<HistoryOsmPrimitive> getPrimitivesByModificationType(ChangesetModificationType cmt) throws IllegalArgumentException {
    148         CheckParameterUtil.ensureParameterNotNull(cmt, "cmt");
    149         HashSet<HistoryOsmPrimitive> ret = new HashSet<>();
    150         for (Entry<PrimitiveId, ChangesetModificationType> entry: modificationTypes.entrySet()) {
    151             if (entry.getValue().equals(cmt)) {
    152                 ret.add(primitives.get(entry.getKey()));
    153             }
    154         }
    155         return ret;
    156     }
    157 
    158     /**
    159      * Replies the number of objects in the dataset
    160      *
    161      * @return the number of objects in the dataset
    162      */
    163     public int size() {
    164         return primitives.size();
    165     }
    166 
    167     /**
    168      * Replies the {@link HistoryOsmPrimitive} with id <code>id</code> from this
    169      * dataset. null, if there is no such primitive in the data set.
    170      *
    171      * @param id the id
    172      * @return  the {@link HistoryOsmPrimitive} with id <code>id</code> from this
    173      * dataset
    174      */
    175     public HistoryOsmPrimitive getPrimitive(PrimitiveId id) {
    176         if (id == null) return null;
    177         return primitives.get(id);
    178     }
    179 
    180     public Iterator<ChangesetDataSetEntry> iterator() {
    181         return new DefaultIterator();
    182     }
    183 
    184     private static class DefaultChangesetDataSetEntry implements ChangesetDataSetEntry {
    185         private final ChangesetModificationType modificationType;
    186         private final HistoryOsmPrimitive primitive;
    187         private final int earliestVersion;
    188 
    189         DefaultChangesetDataSetEntry(ChangesetModificationType modificationType, HistoryOsmPrimitive primitive, int earliestVersion) {
    190             this.modificationType = modificationType;
    191             this.primitive = primitive;
    192             this.earliestVersion = earliestVersion;
    193         }
    194 
    195         @Override
    196         public ChangesetModificationType getModificationType() {
    197             return modificationType;
    198         }
    199 
    200         @Override
    201         public HistoryOsmPrimitive getPrimitive() {
    202             return primitive;
    203         }
    204 
    205         @Override
    206         public int getEarliestVersion() {
    207             return earliestVersion;
    208         }
    209 }
    210 
    211     private class DefaultIterator implements Iterator<ChangesetDataSetEntry> {
    212         private final Iterator<Entry<PrimitiveId, ChangesetModificationType>> typeIterator;
    213 
    214         DefaultIterator() {
    215             typeIterator = modificationTypes.entrySet().iterator();
    216         }
    217 
    218         @Override
    219         public boolean hasNext() {
    220             return typeIterator.hasNext();
    221         }
    222 
    223         @Override
    224         public ChangesetDataSetEntry next() {
    225             Entry<PrimitiveId, ChangesetModificationType> next = typeIterator.next();
    226             ChangesetModificationType type = next.getValue();
    227             HistoryOsmPrimitive primitive = primitives.get(next.getKey());
    228             Integer earliestVersion = earliestVersions.get(next.getKey());
    229             if (earliestVersion == null) earliestVersion = (int) primitive.getVersion();
    230             return new DefaultChangesetDataSetEntry(type, primitive, earliestVersion);
    231         }
    232 
    233         @Override
    234         public void remove() {
    235             throw new UnsupportedOperationException();
    236         }
    237     }
    238 }
  • src/reverter/corehacks/OsmChangesetContentParser.java

     
    1 // License: GPL. For details, see LICENSE file.
    2 package reverter.corehacks;
    3 
    4 import static org.openstreetmap.josm.tools.I18n.tr;
    5 
    6 import java.io.IOException;
    7 import java.io.InputStream;
    8 import java.io.InputStreamReader;
    9 import java.io.StringReader;
    10 import java.io.UnsupportedEncodingException;
    11 import java.util.Date;
    12 
    13 import javax.xml.parsers.ParserConfigurationException;
    14 import javax.xml.parsers.SAXParserFactory;
    15 
    16 import org.openstreetmap.josm.data.coor.LatLon;
    17 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    18 import org.openstreetmap.josm.data.osm.RelationMemberData;
    19 import org.openstreetmap.josm.data.osm.User;
    20 import org.openstreetmap.josm.data.osm.history.HistoryNode;
    21 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
    22 import org.openstreetmap.josm.data.osm.history.HistoryRelation;
    23 import org.openstreetmap.josm.data.osm.history.HistoryWay;
    24 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    25 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    26 import org.openstreetmap.josm.tools.CheckParameterUtil;
    27 import org.openstreetmap.josm.tools.XmlParsingException;
    28 import org.openstreetmap.josm.tools.date.DateUtils;
    29 import org.xml.sax.Attributes;
    30 import org.xml.sax.InputSource;
    31 import org.xml.sax.Locator;
    32 import org.xml.sax.SAXException;
    33 import org.xml.sax.SAXParseException;
    34 import org.xml.sax.helpers.DefaultHandler;
    35 
    36 import reverter.corehacks.ChangesetDataSet.ChangesetModificationType;
    37 
    38 /**
    39  * Parser for OSM changeset content.
    40  *
    41  */
    42 public class OsmChangesetContentParser {
    43 
    44     private final InputSource source;
    45     private final ChangesetDataSet data;
    46 
    47     private class Parser extends DefaultHandler {
    48 
    49         /** the current primitive to be read */
    50         private HistoryOsmPrimitive currentPrimitive;
    51         /** the current change modification type */
    52         private ChangesetDataSet.ChangesetModificationType currentModificationType;
    53 
    54         private Locator locator;
    55 
    56         @Override
    57         public void setDocumentLocator(Locator locator) {
    58             this.locator = locator;
    59         }
    60 
    61         protected void throwException(String message) throws XmlParsingException {
    62             throw new XmlParsingException(
    63                     message
    64             ).rememberLocation(locator);
    65         }
    66 
    67         protected void throwException(Exception e) throws XmlParsingException {
    68             throw new XmlParsingException(
    69                     e
    70             ).rememberLocation(locator);
    71         }
    72 
    73         protected long getMandatoryAttributeLong(Attributes attr, String name) throws SAXException {
    74             String v = attr.getValue(name);
    75             if (v == null) {
    76                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    77             }
    78             Long l = 0L;
    79             try {
    80                 l = Long.parseLong(v);
    81             } catch (NumberFormatException e) {
    82                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
    83             }
    84             if (l < 0) {
    85                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
    86             }
    87             return l;
    88         }
    89 /*
    90         protected long getAttributeLong(Attributes attr, String name, long defaultValue) throws SAXException{
    91             String v = attr.getValue(name);
    92             if (v == null)
    93                 return defaultValue;
    94             Long l = 0l;
    95             try {
    96                 l = Long.parseLong(v);
    97             } catch(NumberFormatException e) {
    98                 throwException(tr("Illegal value for attribute ''{0}'' of type long. Got ''{1}''.", name, v));
    99             }
    100             if (l < 0) {
    101                 throwException(tr("Illegal value for attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
    102             }
    103             return l;
    104         }
    105 */
    106 
    107         protected Double getAttributeDouble(Attributes attr, String name) throws SAXException {
    108             String v = attr.getValue(name);
    109             if (v == null) {
    110                 return null;
    111             }
    112             double d = 0.0;
    113             try {
    114                 d = Double.parseDouble(v);
    115             } catch (NumberFormatException e) {
    116                 throwException(tr("Illegal value for attribute ''{0}'' of type double. Got ''{1}''.", name, v));
    117             }
    118             return d;
    119         }
    120 
    121         protected String getMandatoryAttributeString(Attributes attr, String name) throws SAXException {
    122             String v = attr.getValue(name);
    123             if (v == null) {
    124                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    125             }
    126             return v;
    127         }
    128 /*
    129         protected String getAttributeString(Attributes attr, String name, String defaultValue) {
    130             String v = attr.getValue(name);
    131             if (v == null)
    132                 return defaultValue;
    133             return v;
    134         }
    135 */
    136 
    137         protected boolean getMandatoryAttributeBoolean(Attributes attr, String name) throws SAXException {
    138             String v = attr.getValue(name);
    139             if (v == null) {
    140                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    141             }
    142             if ("true".equals(v)) return true;
    143             if ("false".equals(v)) return false;
    144             throwException(tr("Illegal value for mandatory attribute ''{0}'' of type boolean. Got ''{1}''.", name, v));
    145             // not reached
    146             return false;
    147         }
    148 
    149         protected HistoryOsmPrimitive createPrimitive(Attributes atts, OsmPrimitiveType type) throws SAXException {
    150             long id = getMandatoryAttributeLong(atts, "id");
    151             long version = getMandatoryAttributeLong(atts, "version");
    152             long changesetId = getMandatoryAttributeLong(atts, "changeset");
    153             boolean visible = getMandatoryAttributeBoolean(atts, "visible");
    154             String v = getMandatoryAttributeString(atts, "timestamp");
    155             Date timestamp = DateUtils.fromString(v);
    156             HistoryOsmPrimitive primitive = null;
    157             // Hack: reverter doesn't need user information, so always use User.getAnonymous()
    158             // TODO: Update OsmChangesetContentParser from the core or update core OsmChangesetContentParser to make it usable with reverter
    159             if (type.equals(OsmPrimitiveType.NODE)) {
    160                 Double lat = getAttributeDouble(atts, "lat");
    161                 Double lon = getAttributeDouble(atts, "lon");
    162                 LatLon coor = (lat != null && lon != null) ? new LatLon(lat, lon) : null;
    163                 primitive = new HistoryNode(
    164                         id, version, visible, User.getAnonymous(), changesetId, timestamp, coor
    165                 );
    166 
    167             } else if (type.equals(OsmPrimitiveType.WAY)) {
    168                 primitive = new HistoryWay(
    169                         id, version, visible, User.getAnonymous(), changesetId, timestamp
    170                 );
    171             } else if (type.equals(OsmPrimitiveType.RELATION)) {
    172                 primitive = new HistoryRelation(
    173                         id, version, visible, User.getAnonymous(), changesetId, timestamp
    174                 );
    175             }
    176             return primitive;
    177         }
    178 
    179         protected void startNode(Attributes atts) throws SAXException {
    180             currentPrimitive = createPrimitive(atts, OsmPrimitiveType.NODE);
    181         }
    182 
    183         protected void startWay(Attributes atts) throws SAXException {
    184             currentPrimitive = createPrimitive(atts, OsmPrimitiveType.WAY);
    185         }
    186 
    187         protected void startRelation(Attributes atts) throws SAXException {
    188             currentPrimitive = createPrimitive(atts, OsmPrimitiveType.RELATION);
    189         }
    190 
    191         protected void handleTag(Attributes atts) throws SAXException {
    192             String key = getMandatoryAttributeString(atts, "k");
    193             String value = getMandatoryAttributeString(atts, "v");
    194             currentPrimitive.put(key, value);
    195         }
    196 
    197         protected void handleNodeReference(Attributes atts) throws SAXException {
    198             long ref = getMandatoryAttributeLong(atts, "ref");
    199             ((HistoryWay) currentPrimitive).addNode(ref);
    200         }
    201 
    202         protected void handleMember(Attributes atts) throws SAXException {
    203             long ref = getMandatoryAttributeLong(atts, "ref");
    204             String v = getMandatoryAttributeString(atts, "type");
    205             OsmPrimitiveType type = null;
    206             try {
    207                 type = OsmPrimitiveType.fromApiTypeName(v);
    208             } catch (IllegalArgumentException e) {
    209                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type OsmPrimitiveType. Got ''{1}''.", "type", v));
    210             }
    211             String role = getMandatoryAttributeString(atts, "role");
    212             RelationMemberData member = new RelationMemberData(role, type, ref);
    213             ((HistoryRelation) currentPrimitive).addMember(member);
    214         }
    215 
    216         @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
    217             if (qName.equals("node")) {
    218                 startNode(atts);
    219             } else if (qName.equals("way")) {
    220                 startWay(atts);
    221             } else if (qName.equals("relation")) {
    222                 startRelation(atts);
    223             } else if (qName.equals("tag")) {
    224                 handleTag(atts);
    225             } else if (qName.equals("nd")) {
    226                 handleNodeReference(atts);
    227             } else if (qName.equals("member")) {
    228                 handleMember(atts);
    229             } else if (qName.equals("osmChange")) {
    230                 // do nothing
    231             } else if (qName.equals("create")) {
    232                 currentModificationType = ChangesetModificationType.CREATED;
    233             } else if (qName.equals("modify")) {
    234                 currentModificationType = ChangesetModificationType.UPDATED;
    235             } else if (qName.equals("delete")) {
    236                 currentModificationType = ChangesetModificationType.DELETED;
    237             } else {
    238                 System.err.println(tr("Warning: unsupported start element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
    239                         qName, locator.getLineNumber(), locator.getColumnNumber()));
    240             }
    241         }
    242 
    243         @Override
    244         public void endElement(String uri, String localName, String qName) throws SAXException {
    245             if (qName.equals("node")
    246                     || qName.equals("way")
    247                     || qName.equals("relation")) {
    248                 if (currentModificationType == null) {
    249                     throwException(
    250                             tr("Illegal document structure. Found node, way, or relation outside of ''create'', ''modify'', or ''delete''."));
    251                 }
    252                 data.put(currentPrimitive, currentModificationType);
    253             } else if (qName.equals("osmChange")) {
    254                 // do nothing
    255             } else if (qName.equals("create")) {
    256                 currentModificationType = null;
    257             } else if (qName.equals("modify")) {
    258                 currentModificationType = null;
    259             } else if (qName.equals("delete")) {
    260                 currentModificationType = null;
    261             } else if (qName.equals("tag")) {
    262                 // do nothing
    263             } else if (qName.equals("nd")) {
    264                 // do nothing
    265             } else if (qName.equals("member")) {
    266                 // do nothing
    267             } else {
    268                 System.err.println(tr("Warning: unsupported end element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
    269                         qName, locator.getLineNumber(), locator.getColumnNumber()));
    270             }
    271         }
    272 
    273         @Override
    274         public void error(SAXParseException e) throws SAXException {
    275             throwException(e);
    276         }
    277 
    278         @Override
    279         public void fatalError(SAXParseException e) throws SAXException {
    280             throwException(e);
    281         }
    282     }
    283 
    284     /**
    285      * Create a parser
    286      *
    287      * @param source the input stream with the changeset content as XML document. Must not be null.
    288      * @throws IllegalArgumentException thrown if source is null.
    289      * @throws UnsupportedEncodingException if the named charset is not supported
    290      */
    291     public OsmChangesetContentParser(InputStream source) throws UnsupportedEncodingException {
    292         CheckParameterUtil.ensureParameterNotNull(source, "source");
    293         this.source = new InputSource(new InputStreamReader(source, "UTF-8"));
    294         data = new ChangesetDataSet();
    295     }
    296 
    297     public OsmChangesetContentParser(String source) {
    298         CheckParameterUtil.ensureParameterNotNull(source, "source");
    299         this.source = new InputSource(new StringReader(source));
    300         data = new ChangesetDataSet();
    301     }
    302 
    303     /**
    304      * Parses the content
    305      *
    306      * @param progressMonitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE}
    307      * if null
    308      * @return the parsed data
    309      * @throws XmlParsingException if something went wrong. Check for chained exceptions.
    310      */
    311     public ChangesetDataSet parse(ProgressMonitor progressMonitor) throws XmlParsingException {
    312         if (progressMonitor == null) {
    313             progressMonitor = NullProgressMonitor.INSTANCE;
    314         }
    315         try {
    316             progressMonitor.beginTask("");
    317             progressMonitor.indeterminateSubTask(tr("Parsing changeset content ..."));
    318             SAXParserFactory.newInstance().newSAXParser().parse(source, new Parser());
    319         } catch (XmlParsingException e) {
    320             throw e;
    321         } catch (ParserConfigurationException e) {
    322             throw new XmlParsingException(e);
    323         } catch (SAXException e) {
    324             throw new XmlParsingException(e);
    325         } catch (IOException e) {
    326             throw new XmlParsingException(e);
    327         } finally {
    328             progressMonitor.finishTask();
    329         }
    330         return data;
    331     }
    332 
    333     /**
    334      * Parses the content from the input source
    335      *
    336      * @return the parsed data
    337      * @throws XmlParsingException if something went wrong. Check for chained exceptions.
    338      */
    339     public ChangesetDataSet parse() throws XmlParsingException {
    340         return parse(null);
    341     }
    342 }
  • src/reverter/corehacks/OsmServerChangesetReader.java

     
    1 // License: GPL. For details, see LICENSE file.
    2 package reverter.corehacks;
    3 
    4 import static org.openstreetmap.josm.tools.I18n.tr;
    5 import static org.openstreetmap.josm.tools.I18n.trn;
    6 
    7 import java.io.InputStream;
    8 import java.io.UnsupportedEncodingException;
    9 import java.text.MessageFormat;
    10 import java.util.ArrayList;
    11 import java.util.Collection;
    12 import java.util.Collections;
    13 import java.util.Iterator;
    14 import java.util.List;
    15 
    16 import org.openstreetmap.josm.data.osm.Changeset;
    17 import org.openstreetmap.josm.data.osm.DataSet;
    18 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    19 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    20 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    21 import org.openstreetmap.josm.io.ChangesetQuery;
    22 import org.openstreetmap.josm.io.IllegalDataException;
    23 import org.openstreetmap.josm.io.OsmChangesetParser;
    24 import org.openstreetmap.josm.io.OsmServerReader;
    25 import org.openstreetmap.josm.io.OsmTransferException;
    26 import org.openstreetmap.josm.tools.CheckParameterUtil;
    27 import org.openstreetmap.josm.tools.XmlParsingException;
    28 
    29 /**
    30  * Reads the history of an {@link OsmPrimitive} from the OSM API server.
    31  *
    32  */
    33 public class OsmServerChangesetReader extends OsmServerReader {
    34 
    35     /**
    36      * constructor
    37      *
    38      */
    39     public OsmServerChangesetReader() {
    40         setDoAuthenticate(false);
    41     }
    42 
    43     /**
    44      * don't use - not implemented!
    45      *
    46      */
    47     @Override
    48     public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
    49         return null;
    50     }
    51 
    52     /**
    53      * Queries a list
    54      * @param query  the query specification. Must not be null.
    55      * @param monitor a progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
    56      * @return the list of changesets read from the server or {@code null}
    57      * @throws IllegalArgumentException thrown if query is null
    58      * @throws OsmTransferException thrown if something goes wrong w
    59      */
    60     public List<Changeset> queryChangesets(ChangesetQuery query, ProgressMonitor monitor) throws OsmTransferException {
    61         CheckParameterUtil.ensureParameterNotNull(query, "query");
    62         if (monitor == null) {
    63             monitor = NullProgressMonitor.INSTANCE;
    64         }
    65         try {
    66             monitor.beginTask(tr("Reading changesets..."));
    67             StringBuilder sb = new StringBuilder();
    68             sb.append("changesets?").append(query.getQueryString());
    69             InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
    70             if (in == null)
    71                 return null;
    72             monitor.indeterminateSubTask(tr("Downloading changesets ..."));
    73             return OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true));
    74         } catch (OsmTransferException e) {
    75             throw e;
    76         } catch (IllegalDataException e) {
    77             throw new OsmTransferException(e);
    78         } finally {
    79             monitor.finishTask();
    80         }
    81     }
    82 
    83     /**
    84      * Reads the changeset with id <code>id</code> from the server
    85      *
    86      * @param id  the changeset id. id &gt; 0 required.
    87      * @param monitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
    88      * @return the changeset read
    89      * @throws OsmTransferException thrown if something goes wrong
    90      * @throws IllegalArgumentException if id &lt;= 0
    91      */
    92     public Changeset readChangeset(long id, ProgressMonitor monitor) throws OsmTransferException {
    93         if (id <= 0)
    94             throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected. Got ''{1}''.", "id", id));
    95         if (monitor == null) {
    96             monitor = NullProgressMonitor.INSTANCE;
    97         }
    98         try {
    99             monitor.beginTask(tr("Reading changeset {0} ...", id));
    100             StringBuilder sb = new StringBuilder();
    101             sb.append("changeset/").append(id);
    102             InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
    103             if (in == null)
    104                 return null;
    105             monitor.indeterminateSubTask(tr("Downloading changeset {0} ...", id));
    106             List<Changeset> changesets = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true));
    107             if (changesets == null || changesets.isEmpty())
    108                 return null;
    109             return changesets.get(0);
    110         } catch (OsmTransferException e) {
    111             throw e;
    112         } catch (IllegalDataException e) {
    113             throw new OsmTransferException(e);
    114         } finally {
    115             monitor.finishTask();
    116         }
    117     }
    118 
    119     /**
    120      * Reads the changeset with id <code>id</code> from the server
    121      *
    122      * @param ids  the collection of ids. Ignored if null. Only load changesets for ids &gt; 0.
    123      * @param monitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
    124      * @return the list of changesets read or an empty list or null in case of errors
    125      * @throws OsmTransferException thrown if something goes wrong
    126      * @throws IllegalArgumentException if id &lt;= 0
    127      */
    128     public List<Changeset> readChangesets(Collection<Integer> ids, ProgressMonitor monitor) throws OsmTransferException {
    129         if (ids == null)
    130             return Collections.emptyList();
    131         if (monitor == null) {
    132             monitor = NullProgressMonitor.INSTANCE;
    133         }
    134         try {
    135             monitor.beginTask(trn("Downloading {0} changeset ...", "Downloading {0} changesets ...", ids.size(), ids.size()));
    136             monitor.setTicksCount(ids.size());
    137             List<Changeset> ret = new ArrayList<>();
    138             int i = 0;
    139             for (Iterator<Integer> it = ids.iterator(); it.hasNext();) {
    140                 int id = it.next();
    141                 if (id <= 0) {
    142                     continue;
    143                 }
    144                 i++;
    145                 StringBuilder sb = new StringBuilder();
    146                 sb.append("changeset/").append(id);
    147                 InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
    148                 if (in == null)
    149                     return null;
    150                 monitor.indeterminateSubTask(tr("({0}/{1}) Downloading changeset {2}...", i, ids.size(), id));
    151                 List<Changeset> changesets = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true));
    152                 if (changesets == null || changesets.isEmpty()) {
    153                     continue;
    154                 }
    155                 ret.addAll(changesets);
    156                 monitor.worked(1);
    157             }
    158             return ret;
    159         } catch (OsmTransferException e) {
    160             throw e;
    161         } catch (IllegalDataException e) {
    162             throw new OsmTransferException(e);
    163         } finally {
    164             monitor.finishTask();
    165         }
    166     }
    167 
    168     /**
    169      * Downloads the content of a changeset
    170      *
    171      * @param id the changeset id. &gt;0 required.
    172      * @param monitor the progress monitor. {@link NullProgressMonitor#INSTANCE} assumed if null.
    173      * @return the changeset content
    174      * @throws IllegalArgumentException thrown if id &lt;= 0
    175      * @throws OsmTransferException thrown if something went wrong
    176      */
    177     public ChangesetDataSet downloadChangeset(int id, ProgressMonitor monitor) throws OsmTransferException {
    178         if (id <= 0)
    179             throw new IllegalArgumentException(
    180                     MessageFormat.format("Expected value of type integer > 0 for parameter ''{0}'', got {1}", "id", id));
    181         if (monitor == null) {
    182             monitor = NullProgressMonitor.INSTANCE;
    183         }
    184         try {
    185             monitor.beginTask(tr("Downloading changeset content"));
    186             StringBuilder sb = new StringBuilder();
    187             sb.append("changeset/").append(id).append("/download");
    188             InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
    189             if (in == null)
    190                 return null;
    191             monitor.setCustomText(tr("Downloading content for changeset {0} ...", id));
    192             OsmChangesetContentParser parser = new OsmChangesetContentParser(in);
    193             return parser.parse(monitor.createSubTaskMonitor(1, true));
    194         } catch (UnsupportedEncodingException | XmlParsingException e) {
    195             throw new OsmTransferException(e);
    196         } finally {
    197             monitor.finishTask();
    198         }
    199     }
    200 }