Ticket #2302: timestamp.patch

File timestamp.patch, 16.5 KB (added by jttt, 16 years ago)

Patch to replace timestamp and parsedTimestap with setter/getter

  • src/org/openstreetmap/josm/actions/search/SearchCompiler.java

     
    1616import org.openstreetmap.josm.data.osm.Relation;
    1717import org.openstreetmap.josm.data.osm.User;
    1818import org.openstreetmap.josm.data.osm.Way;
     19import org.openstreetmap.josm.tools.DateUtils;
    1920
    2021/**
    2122 * Implements a google-like search.
     
    145146                String value = null;
    146147
    147148                if (key.equals("timestamp"))
    148                     value = osm.getTimeStr();
     149                    value = DateUtils.fromDate(osm.getTimestamp());
    149150                else
    150151                    value = osm.get(key);
    151152
  • src/org/openstreetmap/josm/tools/DateUtils.java

     
     1/*
     2 *  JOSMng - a Java Open Street Map editor, the next generation.
     3 *
     4 *  Copyright (C) 2008 Petr Nejedly <P.Nejedly@sh.cvut.cz>
     5 *
     6 *  This program is free software; you can redistribute it and/or modify
     7 *  it under the terms of the GNU General Public License as published by
     8 *  the Free Software Foundation; either version 2 of the License, or
     9 *  (at your option) any later version.
     10 *
     11 *  This program is distributed in the hope that it will be useful,
     12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 *  GNU General Public License for more details.
     15
     16 *  You should have received a copy of the GNU General Public License along
     17 *  with this program; if not, write to the Free Software Foundation, Inc.,
     18 *  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
     19 */
     20
     21package org.openstreetmap.josm.tools;
     22
     23import java.util.Calendar;
     24import java.util.Date;
     25import java.util.GregorianCalendar;
     26import java.util.TimeZone;
     27
     28import javax.xml.datatype.DatatypeConfigurationException;
     29import javax.xml.datatype.DatatypeFactory;
     30import javax.xml.datatype.XMLGregorianCalendar;
     31
     32
     33/**
     34 * A static utility class dealing with parsing XML date quickly and formatting
     35 * a date to the XML UTC format regardless of current locale.
     36 *
     37 * @author nenik
     38 */
     39public final class DateUtils {
     40    private DateUtils() {}
     41    /**
     42     * A shared instance used for conversion between individual date fields
     43     * and long millis time. It is guarded against conflict by the class lock.
     44     * The shared instance is used because the construction, together
     45     * with the timezone lookup, is very expensive.
     46     */
     47    private static GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
     48    private static final DatatypeFactory XML_DATE;
     49
     50    static {
     51        calendar.setTimeInMillis(0);
     52       
     53        DatatypeFactory fact = null;
     54        try {
     55            fact = DatatypeFactory.newInstance();
     56        } catch(DatatypeConfigurationException ce) {
     57            ce.printStackTrace();
     58        }
     59        XML_DATE = fact;
     60    }
     61
     62    public static synchronized Date fromString(String str) {
     63        // "2007-07-25T09:26:24{Z|{+|-}01:00}"
     64        if (checkLayout(str, "xxxx-xx-xxTxx:xx:xxZ") ||
     65                checkLayout(str, "xxxx-xx-xxTxx:xx:xx+xx:00") ||
     66                checkLayout(str, "xxxx-xx-xxTxx:xx:xx-xx:00")) {
     67            calendar.set(
     68                parsePart(str, 0, 4),
     69                parsePart(str, 5, 2)-1,
     70                parsePart(str, 8, 2),
     71                parsePart(str, 11, 2),
     72                parsePart(str, 14,2),
     73                parsePart(str, 17, 2));
     74
     75            if (str.length() == 25) {
     76                int plusHr = parsePart(str, 20, 2);
     77                int mul = str.charAt(19) == '+' ? -3600000 : 3600000;
     78                calendar.setTimeInMillis(calendar.getTimeInMillis()+plusHr*mul);
     79            }
     80
     81            return calendar.getTime();
     82        }
     83
     84        try {
     85            return XML_DATE.newXMLGregorianCalendar(str).toGregorianCalendar().getTime();
     86        } catch (Exception ex) {
     87            return new Date();
     88        }
     89    }
     90   
     91    public static synchronized String fromDate(Date date) {
     92        calendar.setTime(date);
     93        XMLGregorianCalendar xgc = XML_DATE.newXMLGregorianCalendar(calendar);
     94        if (calendar.get(Calendar.MILLISECOND) == 0) xgc.setFractionalSecond(null);
     95        return xgc.toXMLFormat();
     96    }
     97       
     98    private static boolean checkLayout(String text, String pattern) {
     99        if (text.length() != pattern.length()) return false;
     100        for (int i=0; i<pattern.length(); i++) {
     101            if (pattern.charAt(i) == 'x') continue;
     102            if (pattern.charAt(i) != text.charAt(i)) return false;
     103        }
     104        return true;
     105    }
     106
     107    private static int parsePart(String str, int off, int len) {
     108        return Integer.valueOf(str.substring(off, off+len));
     109    }
     110
     111}
  • src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

     
    6060import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
    6161import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    6262import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
     63import org.openstreetmap.josm.tools.DateUtils;
    6364import org.openstreetmap.josm.tools.GBC;
    6465import org.openstreetmap.josm.tools.ImageProvider;
    6566
     
    404405                if (!n.tagged) {
    405406                    doneNodes.add(n);
    406407                }
    407                 WayPoint wpt = new WayPoint(n.coor);
    408                 if (n.timestamp != null)
     408                WayPoint wpt = new WayPoint(n.coor);               
     409                if (!n.isTimestampEmpty())
    409410                {
    410                     wpt.attr.put("time", n.timestamp);
     411                    wpt.attr.put("time", DateUtils.fromDate(n.getTimestamp()));
    411412                    wpt.setTime();
    412413                }
    413414                trkseg.add(wpt);
     
    419420        for (Node n : data.nodes) {
    420421            if (n.incomplete || n.deleted || doneNodes.contains(n)) continue;
    421422            WayPoint wpt = new WayPoint(n.coor);
    422             if (n.timestamp != null) {
    423                 wpt.attr.put("time", n.timestamp);
     423            if (!n.isTimestampEmpty()) {
     424                wpt.attr.put("time", DateUtils.fromDate(n.getTimestamp()));
    424425                wpt.setTime();
    425426            }
    426427            if (n.keys != null && n.keys.containsKey("name")) {
  • src/org/openstreetmap/josm/gui/layer/GpxLayer.java

     
    6767import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    6868import org.openstreetmap.josm.gui.layer.markerlayer.AudioMarker;
    6969import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
     70import org.openstreetmap.josm.tools.DateUtils;
    7071import org.openstreetmap.josm.tools.DontShowAgainInfo;
    7172import org.openstreetmap.josm.tools.GBC;
    7273import org.openstreetmap.josm.tools.ImageProvider;
     
    659660                        String timestr = p.getString("time");
    660661                        if(timestr != null)
    661662                        {
    662                             timestr = timestr.replace("Z","+00:00");
    663                             n.timestamp = timestr;
     663                            n.setTimestamp(DateUtils.fromString(timestr));
    664664                        }
    665665                        ds.nodes.add(n);
    666666                        w.nodes.add(n);
  • src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java

     
    3535import org.openstreetmap.josm.data.osm.DataSet;
    3636import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3737import org.openstreetmap.josm.gui.SideButton;
     38import org.openstreetmap.josm.tools.DateUtils;
    3839import org.openstreetmap.josm.tools.GBC;
    3940import org.openstreetmap.josm.tools.ImageProvider;
    4041import org.openstreetmap.josm.tools.Shortcut;
     
    170171                orderedHistory.addAll(cache.get(osm));
    171172            data.setRowCount(0);
    172173            for (HistoryItem i : orderedHistory)
    173                 data.addRow(new Object[]{i.osm, i.osm.timestamp, i.visible});
     174                data.addRow(new Object[]{i.osm, DateUtils.fromDate(i.osm.getTimestamp()), i.visible});
    174175            historyPane.setVisible(true);
    175176            notLoaded.setVisible(false);
    176177        }
  • src/org/openstreetmap/josm/io/OsmReader.java

     
    3232import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
    3333import org.openstreetmap.josm.data.osm.visitor.Visitor;
    3434import org.openstreetmap.josm.gui.PleaseWaitDialog;
     35import org.openstreetmap.josm.tools.DateUtils;
    3536import org.xml.sax.Attributes;
    3637import org.xml.sax.InputSource;
    3738import org.xml.sax.SAXException;
     
    100101               osm.modified = modified;
    101102               osm.selected = selected;
    102103               osm.deleted = deleted;
    103                osm.timestamp = timestamp;
     104               osm.setTimestamp(getTimestamp());
    104105               osm.user = user;
    105106               osm.visible = visible;
    106107               osm.version = version;
     
    296297
    297298          String time = atts.getValue("timestamp");
    298299          if (time != null && time.length() != 0) {
    299                /* Do not parse the date here since it wastes a HUGE amount of time.
    300                 * Moved into OsmPrimitive.
    301                try {
    302                     current.timestamp = DateParser.parse(time);
    303                } catch (ParseException e) {
    304                     e.printStackTrace();
    305                     throw new SAXException(tr("Couldn''t read time format \"{0}\".",time));
    306                }
    307                */
    308                current.timestamp = time;
     300               current.setTimestamp(DateUtils.fromString(time));
    309301          }
    310302
    311303          // user attribute added in 0.4 API
  • src/org/openstreetmap/josm/io/OsmWriter.java

     
    1515import org.openstreetmap.josm.data.osm.Changeset;
    1616import org.openstreetmap.josm.data.osm.Way;
    1717import org.openstreetmap.josm.data.osm.visitor.Visitor;
     18import org.openstreetmap.josm.tools.DateUtils;
    1819
    1920/**
    2021 * Save the dataset into a stream as osm intern xml format. This is not using any
     
    200201            if (action != null)
    201202                out.print(" action='"+action+"'");
    202203        }
    203         if (osm.timestamp != null) {
    204             out.print(" timestamp='"+osm.timestamp+"'");
     204        if (!osm.isTimestampEmpty()) {
     205            out.print(" timestamp='"+DateUtils.fromDate(osm.getTimestamp())+"'");
    205206        }
    206207        // user and visible added with 0.4 API
    207208        if (osm.user != null) {
  • src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java

     
    234234                return true; // no merge needed.
    235235            }
    236236            if (my.realEqual(other, true)) {
    237                 Date myd = my.timestamp == null ? new Date(0) : my.getTimestamp();
    238                 Date otherd = other.timestamp == null ? new Date(0) : other.getTimestamp();
     237                Date myd = my.getTimestamp();
     238                Date otherd = other.getTimestamp();
    239239
    240240                // they differ in modified/timestamp combination only. Auto-resolve it.
    241241                merged.put(other, my);
    242242                if (myd.before(otherd)) {
    243243                    my.modified = other.modified;
    244                     my.timestamp = other.timestamp;
     244                    my.setTimestamp(other.getTimestamp());
    245245                }
    246246                return true; // merge done.
    247247            }
    248248            if (my.id == other.id && my.id != 0) {
    249                 Date myd = my.timestamp == null ? new Date(0) : my.getTimestamp();
    250                 Date otherd = other.timestamp == null ? new Date(0) : other.getTimestamp();
     249                Date myd = my.getTimestamp();
     250                Date otherd = other.getTimestamp();
    251251
    252252                if (my.incomplete || other.incomplete) {
    253253                    if (my.incomplete) {
  • src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.text.ParseException;
    7 import java.text.SimpleDateFormat;
    8 import java.util.Arrays;
    96import java.util.ArrayList;
     7import java.util.Arrays;
    108import java.util.Collection;
    119import java.util.Collections;
    1210import java.util.Date;
    1311import java.util.HashMap;
    14 import java.util.HashSet;
    1512import java.util.Map;
    1613import java.util.Map.Entry;
    1714
    18 import org.openstreetmap.josm.data.osm.visitor.Visitor;
    19 import org.openstreetmap.josm.tools.DateParser;
    2015import org.openstreetmap.josm.Main;
     16import org.openstreetmap.josm.data.osm.visitor.Visitor;
    2117import org.openstreetmap.josm.gui.mappaint.ElemStyle;
    2218
    2319
     
    129125     */
    130126    public volatile boolean highlighted = false;
    131127
     128    private int timestamp;
     129   
     130    public void setTimestamp(Date timestamp) {
     131        this.timestamp = (int)(timestamp.getTime() / 1000);
     132    }
     133   
    132134    /**
    133135     * Time of last modification to this object. This is not set by JOSM but
    134136     * read from the server and delivered back to the server unmodified. It is
    135137     * used to check against edit conflicts.
    136      */
    137     public String timestamp = null;
     138     *
     139     */   
     140    public Date getTimestamp() {
     141        return new Date(timestamp * 1000l);
     142    }
     143   
     144    public boolean isTimestampEmpty() {
     145        return timestamp == 0;
     146    }
    138147
    139148    /**
    140      * The timestamp is only parsed when this is really necessary, and this
    141      * is the cache for the result.
    142      */
    143     public Date parsedTimestamp = null;
    144 
    145     /**
    146149     * If set to true, this object is incomplete, which means only the id
    147150     * and type is known (type is the objects instance class)
    148151     */
     
    182185    }
    183186
    184187    /**
    185      * Returns the timestamp for this object, or the current time if none is set.
    186      * Internally, parses the timestamp from XML into a Date object and caches it
    187      * for possible repeated calls.
    188      */
    189     public Date getTimestamp() {
    190         if (parsedTimestamp == null) {
    191             try {
    192                 parsedTimestamp = DateParser.parse(timestamp);
    193             } catch (ParseException ex) {
    194                 parsedTimestamp = new Date();
    195             }
    196         }
    197         return parsedTimestamp;
    198     }
    199 
    200     /**
    201188     * Equal, if the id (and class) is equal.
    202189     *
    203190     * An primitive is equal to its incomplete counter part.
     
    308295            incomplete == osm.incomplete &&
    309296            (semanticOnly || (modified == osm.modified)) &&
    310297            deleted == osm.deleted &&
    311             (semanticOnly || (timestamp == null ? osm.timestamp==null : timestamp.equals(osm.timestamp))) &&
     298            (semanticOnly || timestamp == osm.timestamp) &&
    312299            (semanticOnly || (version==osm.version)) &&
    313300            (semanticOnly || (user == null ? osm.user==null : user==osm.user)) &&
    314301            (semanticOnly || (visible == osm.visible)) &&
    315302            (keys == null ? osm.keys==null : keys.equals(osm.keys));
    316303    }
    317304
    318     public String getTimeStr() {
    319         return timestamp == null ? null : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp);
    320     }
    321 
    322305    /**
    323306     * Updates the "tagged" flag. "keys" property should probably be made private
    324307     * to make sure this gets called when keys are set.