001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.io;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    import static org.openstreetmap.josm.tools.I18n.trn;
006    
007    import java.io.InputStream;
008    import java.io.UnsupportedEncodingException;
009    import java.text.MessageFormat;
010    import java.util.ArrayList;
011    import java.util.Collection;
012    import java.util.Collections;
013    import java.util.Iterator;
014    import java.util.List;
015    
016    import org.openstreetmap.josm.data.osm.Changeset;
017    import org.openstreetmap.josm.data.osm.ChangesetDataSet;
018    import org.openstreetmap.josm.data.osm.DataSet;
019    import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
020    import org.openstreetmap.josm.gui.progress.ProgressMonitor;
021    import org.openstreetmap.josm.tools.CheckParameterUtil;
022    
023    /**
024     * Reads the history of an {@link OsmPrimitive} from the OSM API server.
025     *
026     */
027    public class OsmServerChangesetReader extends OsmServerReader {
028    
029        /**
030         * constructor
031         *
032         */
033        public OsmServerChangesetReader(){
034            setDoAuthenticate(false);
035        }
036    
037        /**
038         * don't use - not implemented!
039         *
040         */
041        @Override
042        public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
043            return null;
044        }
045    
046        /**
047         * Queries a list
048         * @param query  the query specification. Must not be null.
049         * @param monitor a progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
050         * @return the list of changesets read from the server
051         * @throws IllegalArgumentException thrown if query is null
052         * @throws OsmTransferException thrown if something goes wrong w
053         */
054        public List<Changeset> queryChangesets(ChangesetQuery query, ProgressMonitor monitor) throws OsmTransferException {
055            CheckParameterUtil.ensureParameterNotNull(query, "query");
056            if (monitor == null) {
057                monitor = NullProgressMonitor.INSTANCE;
058            }
059            try {
060                monitor.beginTask(tr("Reading changesets..."));
061                StringBuffer sb = new StringBuffer();
062                sb.append("changesets?").append(query.getQueryString());
063                InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
064                if (in == null)
065                    return null;
066                monitor.indeterminateSubTask(tr("Downloading changesets ..."));
067                List<Changeset> changesets = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true));
068                return changesets;
069            } catch(OsmTransferException e) {
070                throw e;
071            } catch(IllegalDataException e) {
072                throw new OsmTransferException(e);
073            } finally {
074                monitor.finishTask();
075            }
076        }
077    
078        /**
079         * Reads the changeset with id <code>id</code> from the server
080         *
081         * @param id  the changeset id. id > 0 required.
082         * @param monitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
083         * @return the changeset read
084         * @throws OsmTransferException thrown if something goes wrong
085         * @throws IllegalArgumentException if id <= 0
086         */
087        public Changeset readChangeset(long id, ProgressMonitor monitor) throws OsmTransferException {
088            if (id <= 0)
089                throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected. Got ''{1}''.", "id", id));
090            if (monitor == null) {
091                monitor = NullProgressMonitor.INSTANCE;
092            }
093            try {
094                monitor.beginTask(tr("Reading changeset {0} ...",id));
095                StringBuffer sb = new StringBuffer();
096                sb.append("changeset/").append(id);
097                InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
098                if (in == null)
099                    return null;
100                monitor.indeterminateSubTask(tr("Downloading changeset {0} ...", id));
101                List<Changeset> changesets = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true));
102                if (changesets == null || changesets.isEmpty())
103                    return null;
104                return changesets.get(0);
105            } catch(OsmTransferException e) {
106                throw e;
107            } catch(IllegalDataException e) {
108                throw new OsmTransferException(e);
109            } finally {
110                monitor.finishTask();
111            }
112        }
113    
114        /**
115         * Reads the changeset with id <code>id</code> from the server
116         *
117         * @param ids  the list of ids. Ignored if null. Only load changesets for ids > 0.
118         * @param monitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
119         * @return the changeset read
120         * @throws OsmTransferException thrown if something goes wrong
121         * @throws IllegalArgumentException if id <= 0
122         */
123        public List<Changeset> readChangesets(Collection<Integer> ids, ProgressMonitor monitor) throws OsmTransferException {
124            if (ids == null)
125                return Collections.emptyList();
126            if (monitor == null) {
127                monitor = NullProgressMonitor.INSTANCE;
128            }
129            try {
130                monitor.beginTask(trn("Downloading {0} changeset ...", "Downloading {0} changesets ...",ids.size(),ids.size()));
131                monitor.setTicksCount(ids.size());
132                List<Changeset> ret = new ArrayList<Changeset>();
133                int i=0;
134                for (Iterator<Integer> it = ids.iterator(); it.hasNext(); ) {
135                    int id = it.next();
136                    if (id <= 0) {
137                        continue;
138                    }
139                    i++;
140                    StringBuffer sb = new StringBuffer();
141                    sb.append("changeset/").append(id);
142                    InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
143                    if (in == null)
144                        return null;
145                    monitor.indeterminateSubTask(tr("({0}/{1}) Downloading changeset {2} ...", i,ids.size(), id));
146                    List<Changeset> changesets = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true));
147                    if (changesets == null || changesets.isEmpty()) {
148                        continue;
149                    }
150                    ret.addAll(changesets);
151                    monitor.worked(1);
152                }
153                return ret;
154            } catch(OsmTransferException e) {
155                throw e;
156            } catch(IllegalDataException e) {
157                throw new OsmTransferException(e);
158            } finally {
159                monitor.finishTask();
160            }
161        }
162    
163        /**
164         * Downloads the content of a changeset
165         *
166         * @param id the changeset id. >0 required.
167         * @param monitor the progress monitor. {@link NullProgressMonitor#INSTANCE} assumed if null.
168         * @return the changeset content
169         * @throws IllegalArgumentException thrown if id <= 0
170         * @throws OsmTransferException thrown if something went wrong
171         */
172        public ChangesetDataSet downloadChangeset(int id, ProgressMonitor monitor) throws IllegalArgumentException, OsmTransferException {
173            if (id <= 0)
174                throw new IllegalArgumentException(MessageFormat.format("Expected value of type integer > 0 for parameter ''{0}'', got {1}", "id", id));
175            if (monitor == null) {
176                monitor = NullProgressMonitor.INSTANCE;
177            }
178            try {
179                monitor.beginTask(tr("Downloading changeset content"));
180                StringBuffer sb = new StringBuffer();
181                sb.append("changeset/").append(id).append("/download");
182                InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true));
183                if (in == null)
184                    return null;
185                monitor.setCustomText(tr("Downloading content for changeset {0} ...", id));
186                OsmChangesetContentParser parser = new OsmChangesetContentParser(in);
187                ChangesetDataSet ds = parser.parse(monitor.createSubTaskMonitor(1, true));
188                return ds;
189            } catch(UnsupportedEncodingException e) {
190                throw new OsmTransferException(e);
191            } catch(OsmDataParsingException e) {
192                throw new OsmTransferException(e);
193            } finally {
194                monitor.finishTask();
195            }
196        }
197    }