Ticket #2302: timestamp.patch

File timestamp.patch, 16.5 KB (added by jttt, 3 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.