001package jmri.implementation; 002 003import com.fasterxml.jackson.databind.util.StdDateFormat; 004 005import java.text.*; 006import java.util.Calendar; 007import java.util.Date; 008import java.util.Objects; 009 010import javax.annotation.CheckForNull; 011 012import jmri.*; 013 014import org.jdom2.Element; 015import org.slf4j.Logger; 016import org.slf4j.LoggerFactory; 017 018/** 019 * Concrete implementation of the {@link jmri.IdTag} interface for the Internal 020 * system. 021 * <hr> 022 * This file is part of JMRI. 023 * <p> 024 * JMRI is free software; you can redistribute it and/or modify it under the 025 * terms of version 2 of the GNU General Public License as published by the Free 026 * Software Foundation. See the "COPYING" file for a copy of this license. 027 * <p> 028 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 029 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 030 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 031 * 032 * @author Matthew Harris Copyright (C) 2011 033 * @since 2.11.4 034 */ 035public class DefaultIdTag extends AbstractIdTag { 036 037 private int currentState = UNKNOWN; 038 039 public DefaultIdTag(String systemName) { 040 super(systemName); 041 setWhereLastSeen(null); 042 } 043 044 public DefaultIdTag(String systemName, String userName) { 045 super(systemName, userName); 046 setWhereLastSeen(null); 047 } 048 049 @Override 050 public int compareTo(NamedBean n2) { 051 Objects.requireNonNull(n2); 052 String o1 = this.getSystemName(); 053 String o2 = n2.getSystemName(); 054 int p1len = Manager.getSystemPrefixLength(o1); 055 int p2len = Manager.getSystemPrefixLength(o2); 056 int comp = o1.substring(0, p1len).compareTo(o2.substring(0, p2len)); 057 if (comp != 0) 058 return comp; 059 comp = o1.compareTo(o2); 060 return comp; 061 } 062 063 @Override 064 public final void setWhereLastSeen(@CheckForNull Reporter r) { 065 Reporter oldWhere = this.whereLastSeen; 066 Date oldWhen = this.whenLastSeen; 067 this.whereLastSeen = r; 068 if (r != null) { 069 this.whenLastSeen = getDateNow(); 070 } else { 071 this.whenLastSeen = null; 072 } 073 setCurrentState(r != null ? SEEN : UNSEEN); 074 firePropertyChange("whereLastSeen", oldWhere, this.whereLastSeen); // NOI18N 075 firePropertyChange("whenLastSeen", oldWhen, this.whenLastSeen); // NOI18N 076 } 077 078 private Date getDateNow() { 079 return InstanceManager.getDefault(IdTagManager.class).isFastClockUsed() 080 ? InstanceManager.getDefault(ClockControl.class).getTime() 081 : Calendar.getInstance().getTime(); 082 } 083 084 private void setCurrentState(int state) { 085 try { 086 setState(state); 087 } catch (JmriException ex) { 088 log.warn("Problem setting state of IdTag {} {}", getSystemName(),ex.getMessage()); 089 } 090 } 091 092 @Override 093 public void setState(int s) throws JmriException { 094 this.currentState = s; 095 } 096 097 @Override 098 public int getState() { 099 return this.currentState; 100 } 101 102 @Override 103 public Element store(boolean storeState) { 104 Element e = new Element("idtag"); // NOI18N 105 e.addContent(new Element("systemName").addContent(this.mSystemName)); // NOI18N 106 String uName = this.getUserName(); 107 if (uName != null && !uName.isEmpty()) { 108 e.addContent(new Element("userName").addContent(uName)); // NOI18N 109 } 110 String comment = this.getComment(); 111 if ((comment != null) && (!comment.isEmpty())) { 112 e.addContent(new Element("comment").addContent(comment)); // NOI18N 113 } 114 Reporter whereLast = this.getWhereLastSeen(); 115 if (whereLast != null && storeState) { 116 e.addContent(new Element("whereLastSeen").addContent(whereLast.getSystemName())); // NOI18N 117 } 118 if (this.getWhenLastSeen() != null && storeState) { 119 e.addContent(new Element("whenLastSeen").addContent(new StdDateFormat().format(this.getWhenLastSeen()))); 120 } 121 return e; 122 } 123 124 /** 125 * Load an idtag xml element. 126 * whenLastSeen formats accepted JMRI 5.3.6 include 127 * yyyy-MM-dd'T'HH:mm:ss.SSSX 128 * yyyy-MM-dd'T'HH:mm:ss.SSS 129 * EEE, dd MMM yyyy HH:mm:ss zzz 130 * 131 * @param e element to load. 132 */ 133 @Override 134 public void load(Element e) { 135 if (e.getName().equals("idtag")) { // NOI18N 136 log.debug("Load IdTag element for {}", this.getSystemName()); 137 if (e.getChild("userName") != null) { // NOI18N 138 this.setUserName(e.getChild("userName").getText()); // NOI18N 139 } 140 if (e.getChild("comment") != null) { // NOI18N 141 this.setComment(e.getChild("comment").getText()); // NOI18N 142 } 143 if (e.getChild("whereLastSeen") != null) { // NOI18N 144 try { 145 Reporter r = InstanceManager.getDefault(ReporterManager.class) 146 .provideReporter(e.getChild("whereLastSeen").getText()); // NOI18N 147 this.setWhereLastSeen(r); 148 this.whenLastSeen = null; 149 } catch (IllegalArgumentException ex) { 150 log.warn("Failed to provide Reporter \"{}\" in load of \"{}\"", e.getChild("whereLastSeen").getText(), getDisplayName()); 151 } 152 } 153 if (e.getChild("whenLastSeen") != null) { // NOI18N 154 String lastSeenText = e.getChildText("whenLastSeen"); 155 log.debug("Loading {} When Last Seen: {}", getDisplayName(), lastSeenText); 156 try { // parse using ISO 8601 date format 157 this.whenLastSeen = new StdDateFormat().parse(lastSeenText); 158 } catch (ParseException ex) { 159 log.debug("ParseException in whenLastSeen ISO attempt: \"{}\"", lastSeenText, ex); 160 // next, try parse using how it was saved by JMRI < 5.3.5 161 try { 162 this.whenLastSeen = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).parse(lastSeenText); 163 } catch (ParseException ex2) { 164 log.warn("During load of IdTag \"{}\" {}", getDisplayName(), ex.getMessage()); 165 } 166 } 167 } 168 } else { 169 log.error("Not an IdTag element: \"{}\" for Tag \"{}\"", e.getName(), this.getDisplayName()); 170 } 171 } 172 173 private static final Logger log = LoggerFactory.getLogger(DefaultIdTag.class); 174 175}