Commit 99c713c04eb944562a94a79c3477d0e7fbb66f1b
- Diff rendering mode:
- inline
- side by side
|   | |||
| 22 | 22 | package eu.cdauth.osm.lib.api06; | |
| 23 | 23 | ||
| 24 | 24 | import eu.cdauth.osm.lib.*; | |
| 25 | import java.io.Externalizable; | ||
| 26 | import java.io.IOException; | ||
| 27 | import java.io.ObjectInput; | ||
| 28 | import java.io.ObjectOutput; | ||
| 25 | 29 | import org.w3c.dom.Element; | |
| 26 | 30 | import org.w3c.dom.NodeList; | |
| 27 | 31 | ||
| … | … | ||
| 37 | 37 | ||
| 38 | 38 | public class API06Changeset extends API06Item implements Changeset | |
| 39 | 39 | { | |
| 40 | private Hashtable<ChangeType, VersionedItem[]> m_content = null; | ||
| 40 | private Map<ChangeType, VersionedItem[]> m_content = null; | ||
| 41 | 41 | ||
| 42 | private Date m_creation = null; | ||
| 43 | private Date m_closing = null; | ||
| 44 | private User m_user = null; | ||
| 45 | |||
| 46 | @Override | ||
| 47 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 48 | { | ||
| 49 | super.readExternal(in); | ||
| 50 | m_content = (Map<ChangeType, VersionedItem[]>)in.readObject(); | ||
| 51 | m_creation = (Date)in.readObject(); | ||
| 52 | m_closing = (Date)in.readObject(); | ||
| 53 | m_user = (User)in.readObject(); | ||
| 54 | } | ||
| 55 | |||
| 56 | @Override | ||
| 57 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 58 | { | ||
| 59 | super.writeExternal(out); | ||
| 60 | out.writeObject(m_content); | ||
| 61 | out.writeObject(m_creation); | ||
| 62 | out.writeObject(m_closing); | ||
| 63 | out.writeObject(m_user); | ||
| 64 | } | ||
| 65 | |||
| 42 | 66 | /** | |
| 43 | 67 | * Contains the uncleaned osmChange XML element. | |
| 44 | 68 | */ | |
| 45 | private Element m_uncleanedDom = null; | ||
| 69 | private Element m_uncleanedDom = null; // FIXME: Do not serialize | ||
| 46 | 70 | ||
| 47 | 71 | /** | |
| 48 | 72 | * Only for serialization. | |
| … | … | ||
| 79 | 79 | protected API06Changeset(Element a_dom, API06API a_api) | |
| 80 | 80 | { | |
| 81 | 81 | super(a_dom, a_api); | |
| 82 | } | ||
| 83 | 82 | ||
| 84 | @Override | ||
| 85 | public Date getCreationDate() | ||
| 86 | { | ||
| 87 | 83 | try | |
| 88 | 84 | { | |
| 89 | return API06GeographicalItem.getDateFormat().parse(getDOM().getAttribute("created_at")); | ||
| 85 | m_creation = API06GeographicalItem.getDateFormat().parse(a_dom.getAttribute("created_at")); | ||
| 90 | 86 | } | |
| 91 | 87 | catch(ParseException e) | |
| 92 | 88 | { | |
| 93 | return null; | ||
| 94 | 89 | } | |
| 95 | } | ||
| 96 | 90 | ||
| 97 | @Override | ||
| 98 | public Date getClosingDate() | ||
| 99 | { | ||
| 100 | 91 | try | |
| 101 | 92 | { | |
| 102 | return API06GeographicalItem.getDateFormat().parse(getDOM().getAttribute("closed_at")); | ||
| 93 | m_closing = API06GeographicalItem.getDateFormat().parse(a_dom.getAttribute("closed_at")); | ||
| 103 | 94 | } | |
| 104 | 95 | catch(ParseException e) | |
| 105 | 96 | { | |
| 106 | return null; | ||
| 107 | 97 | } | |
| 98 | |||
| 99 | m_user = new User(new ID(a_dom.getAttribute("uid")), a_dom.getAttribute("user")); | ||
| 108 | 100 | } | |
| 109 | 101 | ||
| 110 | 102 | @Override | |
| 103 | public Date getCreationDate() | ||
| 104 | { | ||
| 105 | return m_creation; | ||
| 106 | } | ||
| 107 | |||
| 108 | @Override | ||
| 109 | public Date getClosingDate() | ||
| 110 | { | ||
| 111 | return m_closing; | ||
| 112 | } | ||
| 113 | |||
| 114 | @Override | ||
| 111 | 115 | public User getUser() | |
| 112 | 116 | { | |
| 113 | return new User(new ID(getDOM().getAttribute("uid")), getDOM().getAttribute("user")); | ||
| 117 | return m_user; | ||
| 114 | 118 | } | |
| 115 | 119 | ||
| 116 | 120 | /** |
|   | |||
| 23 | 23 | ||
| 24 | 24 | import java.text.ParseException; | |
| 25 | 25 | import java.text.SimpleDateFormat; | |
| 26 | import java.util.Collection; | ||
| 27 | 26 | import java.util.Date; | |
| 28 | 27 | ||
| 29 | 28 | import eu.cdauth.osm.lib.*; | |
| 30 | 29 | import org.w3c.dom.Element; | |
| 31 | 30 | ||
| 32 | 31 | import eu.cdauth.osm.lib.GeographicalItem; | |
| 32 | import java.io.IOException; | ||
| 33 | import java.io.ObjectInput; | ||
| 34 | import java.io.ObjectOutput; | ||
| 35 | import java.util.Arrays; | ||
| 36 | import java.util.SimpleTimeZone; | ||
| 33 | 37 | ||
| 34 | 38 | abstract public class API06GeographicalItem extends API06Item implements VersionedItem, GeographicalItem | |
| 35 | 39 | { | |
| 36 | private static SimpleDateFormat sm_dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); | ||
| 40 | private static final SimpleDateFormat sm_dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); | ||
| 41 | static { | ||
| 42 | sm_dateFormat.setTimeZone(new SimpleTimeZone(0, "UTC")); | ||
| 43 | } | ||
| 37 | 44 | ||
| 38 | private boolean m_current = false; | ||
| 45 | private boolean m_current = false; // FIXME: Serialize? | ||
| 39 | 46 | ||
| 47 | private Date m_timestamp = null; | ||
| 48 | private Version m_version = null; | ||
| 49 | private ID m_changeset = null; | ||
| 40 | 50 | private ID[] m_containingRelations = null; | |
| 41 | 51 | ||
| 52 | @Override | ||
| 53 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 54 | { | ||
| 55 | super.readExternal(in); | ||
| 56 | m_current = in.readBoolean(); | ||
| 57 | m_timestamp = (Date)in.readObject(); | ||
| 58 | m_version = (Version)in.readObject(); | ||
| 59 | m_changeset = (ID)in.readObject(); | ||
| 60 | m_containingRelations = (ID[])in.readObject(); | ||
| 61 | } | ||
| 62 | |||
| 63 | @Override | ||
| 64 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 65 | { | ||
| 66 | super.writeExternal(out); | ||
| 67 | out.writeBoolean(m_current); | ||
| 68 | out.writeObject(m_timestamp); | ||
| 69 | out.writeObject(m_version); | ||
| 70 | out.writeObject(m_changeset); | ||
| 71 | out.writeObject(m_containingRelations); | ||
| 72 | } | ||
| 73 | |||
| 42 | 74 | /** | |
| 43 | 75 | * Only for serialization. | |
| 44 | 76 | */ | |
| … | … | ||
| 87 | 87 | protected API06GeographicalItem(Element a_dom, API06API a_api) | |
| 88 | 88 | { | |
| 89 | 89 | super(a_dom, a_api); | |
| 90 | |||
| 91 | try | ||
| 92 | { | ||
| 93 | m_timestamp = getDateFormat().parse(a_dom.getAttribute("timestamp")); | ||
| 94 | } | ||
| 95 | catch(ParseException e) | ||
| 96 | { | ||
| 97 | } | ||
| 98 | |||
| 99 | String version = a_dom.getAttribute("version"); | ||
| 100 | if(!version.equals("")) | ||
| 101 | m_version = new Version(version); | ||
| 102 | |||
| 103 | m_changeset = new ID(a_dom.getAttribute("changeset")); | ||
| 90 | 104 | } | |
| 91 | 105 | ||
| 92 | 106 | /** | |
| … | … | ||
| 123 | 123 | @Override | |
| 124 | 124 | public Date getTimestamp() | |
| 125 | 125 | { | |
| 126 | try | ||
| 127 | { | ||
| 128 | return getDateFormat().parse(getDOM().getAttribute("timestamp")); | ||
| 129 | } | ||
| 130 | catch(ParseException e) | ||
| 131 | { | ||
| 132 | return null; | ||
| 133 | } | ||
| 126 | return m_timestamp; | ||
| 134 | 127 | } | |
| 135 | 128 | ||
| 136 | 129 | @Override | |
| … | … | ||
| 139 | 139 | @Override | |
| 140 | 140 | public Version getVersion() | |
| 141 | 141 | { | |
| 142 | String version = getDOM().getAttribute("version"); | ||
| 143 | if(version.equals("")) | ||
| 144 | return null; | ||
| 145 | return new Version(version); | ||
| 142 | return m_version; | ||
| 146 | 143 | } | |
| 147 | 144 | ||
| 148 | 145 | @Override | |
| 149 | 146 | public ID getChangeset() | |
| 150 | 147 | { | |
| 151 | return new ID(getDOM().getAttribute("changeset")); | ||
| 148 | return m_changeset; | ||
| 152 | 149 | } | |
| 153 | 150 | ||
| 154 | 151 | @Override | |
| 155 | public Relation[] getContainingRelations() throws APIError | ||
| 152 | public ID[] getContainingRelations() throws APIError | ||
| 156 | 153 | { | |
| 157 | 154 | if(m_containingRelations == null) | |
| 158 | 155 | { | |
| … | … | ||
| 164 | 164 | throw new RuntimeException("Unknown data type."); | |
| 165 | 165 | ||
| 166 | 166 | Item[] relations = getAPI().get("/"+urlPart+"/"+getID()+"/relations"); | |
| 167 | Relation[] ret = new Relation[relations.length]; | ||
| 168 | for(int i=0; i<relations.length; i++) | ||
| 169 | ret[i] = (Relation)relations[i]; | ||
| 167 | m_containingRelations = new ID[relations.length]; | ||
| 170 | 168 | VersionedItemCache<Relation> cache = getAPI().getRelationFactory().getCache(); | |
| 171 | for(Relation it : ret) | ||
| 169 | for(int i=0; i<relations.length; i++) | ||
| 172 | 170 | { | |
| 173 | ((API06Relation)it).markAsCurrent(); | ||
| 174 | cache.cacheObject(it); | ||
| 171 | m_containingRelations[i] = relations[i].getID(); | ||
| 172 | ((API06Relation)relations[i]).markAsCurrent(); | ||
| 173 | cache.cacheObject((Relation)relations[i]); | ||
| 175 | 174 | } | |
| 176 | |||
| 177 | synchronized(this) | ||
| 178 | {// TODO This does not seem to be useful | ||
| 179 | m_containingRelations = new ID[ret.length]; | ||
| 180 | for(int i=0; i<ret.length; i++) | ||
| 181 | m_containingRelations[i] = ret[i].getID(); | ||
| 182 | } | ||
| 183 | |||
| 184 | return ret; | ||
| 185 | 175 | } | |
| 186 | else | ||
| 187 | { | ||
| 188 | Collection<Relation> ret = getAPI().getRelationFactory().fetch(m_containingRelations).values(); | ||
| 189 | return ret.toArray(new Relation[ret.size()]); | ||
| 190 | } | ||
| 176 | |||
| 177 | return Arrays.copyOf(m_containingRelations, m_containingRelations.length); | ||
| 191 | 178 | } | |
| 192 | 179 | } |
|   | |||
| 21 | 21 | ||
| 22 | 22 | package eu.cdauth.osm.lib.api06; | |
| 23 | 23 | ||
| 24 | import eu.cdauth.osm.lib.Changeset; | ||
| 25 | import java.io.IOException; | ||
| 26 | import java.io.ObjectInput; | ||
| 27 | import java.io.ObjectOutput; | ||
| 24 | 28 | import java.util.Hashtable; | |
| 25 | 29 | import java.util.Map; | |
| 26 | 30 | ||
| … | … | ||
| 33 | 33 | import org.w3c.dom.NodeList; | |
| 34 | 34 | ||
| 35 | 35 | import eu.cdauth.osm.lib.ID; | |
| 36 | import eu.cdauth.osm.lib.Node; | ||
| 37 | import eu.cdauth.osm.lib.Relation; | ||
| 38 | import eu.cdauth.osm.lib.VersionedItem; | ||
| 39 | import eu.cdauth.osm.lib.Way; | ||
| 40 | import java.io.Externalizable; | ||
| 41 | import java.util.Collections; | ||
| 36 | 42 | ||
| 37 | 43 | /** | |
| 38 | 44 | * Parent class for all geographical objects in OSM, currently Nodes, Ways and Relations. | |
| … | … | ||
| 46 | 46 | ||
| 47 | 47 | abstract public class API06Item extends API06XMLItem implements Item | |
| 48 | 48 | { | |
| 49 | private Hashtable<String,String> m_tags = null; | ||
| 49 | private ID m_id = null; | ||
| 50 | private Map<String,String> m_tags = null; | ||
| 50 | 51 | ||
| 52 | @Override | ||
| 53 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 54 | { | ||
| 55 | super.readExternal(in); | ||
| 56 | m_id = (ID)in.readObject(); | ||
| 57 | m_tags = (Map<String,String>)in.readObject(); | ||
| 58 | } | ||
| 59 | |||
| 60 | @Override | ||
| 61 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 62 | { | ||
| 63 | super.writeExternal(out); | ||
| 64 | out.writeObject(m_id); | ||
| 65 | out.writeObject(m_tags); | ||
| 66 | } | ||
| 67 | |||
| 51 | 68 | /** | |
| 52 | 69 | * Only for serialization. | |
| 53 | 70 | */ | |
| … | … | ||
| 76 | 76 | protected API06Item(Element a_dom, API06API a_api) | |
| 77 | 77 | { | |
| 78 | 78 | super(a_dom, a_api); | |
| 79 | |||
| 80 | m_id = new ID(a_dom.getAttribute("id")); | ||
| 81 | |||
| 82 | m_tags = new Hashtable<String,String>(); | ||
| 83 | NodeList tags = a_dom.getElementsByTagName("tag"); | ||
| 84 | for(int i=0; i<tags.getLength(); i++) | ||
| 85 | { | ||
| 86 | if(tags.item(i).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE) | ||
| 87 | continue; | ||
| 88 | Element item = (Element) tags.item(i); | ||
| 89 | String key = item.getAttribute("k"); | ||
| 90 | if(m_tags.containsKey(key)) | ||
| 91 | m_tags.put(key, m_tags.get(key)+","+item.getAttribute("v")); | ||
| 92 | else | ||
| 93 | m_tags.put(key, item.getAttribute("v")); | ||
| 94 | } | ||
| 79 | 95 | } | |
| 80 | 96 | ||
| 81 | 97 | /** | |
| … | … | ||
| 100 | 100 | @Override | |
| 101 | 101 | public boolean equals(java.lang.Object a_other) | |
| 102 | 102 | { | |
| 103 | if(a_other instanceof API06Item) | ||
| 103 | if(!(a_other instanceof Item)) | ||
| 104 | return false; | ||
| 105 | if(!((Item)a_other).getID().equals(getID())) | ||
| 106 | return false; | ||
| 107 | if(a_other instanceof VersionedItem) | ||
| 104 | 108 | { | |
| 105 | API06Item other = (API06Item) a_other; | ||
| 106 | return (getDOM().getTagName().equals(other.getDOM().getTagName()) && !getDOM().getAttribute("id").equals("") && getDOM().getAttribute("id").equals(other.getDOM().getAttribute("id")) && getDOM().getAttribute("version").equals(other.getDOM().getAttribute("version"))); | ||
| 109 | if(!(this instanceof VersionedItem)) | ||
| 110 | return false; | ||
| 111 | if(!((VersionedItem)a_other).getVersion().equals(((VersionedItem)this).getVersion())) | ||
| 112 | return false; | ||
| 107 | 113 | } | |
| 108 | else | ||
| 109 | return false; | ||
| 114 | |||
| 115 | if(a_other instanceof Node && this instanceof Node) | ||
| 116 | return true; | ||
| 117 | if(a_other instanceof Way && this instanceof Way) | ||
| 118 | return true; | ||
| 119 | if(a_other instanceof Relation && this instanceof Relation) | ||
| 120 | return true; | ||
| 121 | if(a_other instanceof Changeset && this instanceof Changeset) | ||
| 122 | return true; | ||
| 123 | |||
| 124 | return false; | ||
| 110 | 125 | } | |
| 111 | 126 | ||
| 112 | 127 | @Override | |
| … | … | ||
| 139 | 139 | @Override | |
| 140 | 140 | public ID getID() | |
| 141 | 141 | { | |
| 142 | return new ID(getDOM().getAttribute("id")); | ||
| 142 | return m_id; | ||
| 143 | 143 | } | |
| 144 | 144 | ||
| 145 | 145 | @Override | |
| … | … | ||
| 152 | 152 | @Override | |
| 153 | 153 | public Map<String,String> getTags() | |
| 154 | 154 | { | |
| 155 | if(m_tags == null) | ||
| 156 | { | ||
| 157 | m_tags = new Hashtable<String,String>(); | ||
| 158 | NodeList tags = getDOM().getElementsByTagName("tag"); | ||
| 159 | for(int i=0; i<tags.getLength(); i++) | ||
| 160 | { | ||
| 161 | if(tags.item(i).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE) | ||
| 162 | continue; | ||
| 163 | Element item = (Element) tags.item(i); | ||
| 164 | String key = item.getAttribute("k"); | ||
| 165 | if(m_tags.containsKey(key)) | ||
| 166 | m_tags.put(key, m_tags.get(key)+","+item.getAttribute("v")); | ||
| 167 | else | ||
| 168 | m_tags.put(key, item.getAttribute("v")); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | return m_tags; | ||
| 155 | return Collections.unmodifiableMap(m_tags); | ||
| 172 | 156 | } | |
| 173 | 157 | } |
|   | |||
| 24 | 24 | import org.w3c.dom.Element; | |
| 25 | 25 | ||
| 26 | 26 | import eu.cdauth.osm.lib.APIError; | |
| 27 | import eu.cdauth.osm.lib.ID; | ||
| 28 | import eu.cdauth.osm.lib.Item; | ||
| 27 | 29 | import eu.cdauth.osm.lib.LonLat; | |
| 28 | 30 | import eu.cdauth.osm.lib.Node; | |
| 29 | 31 | import eu.cdauth.osm.lib.VersionedItemCache; | |
| 30 | 32 | import eu.cdauth.osm.lib.Way; | |
| 33 | import java.io.IOException; | ||
| 34 | import java.io.ObjectInput; | ||
| 35 | import java.io.ObjectOutput; | ||
| 36 | import java.util.Arrays; | ||
| 31 | 37 | ||
| 32 | 38 | /** | |
| 33 | 39 | * Represents a Node in OpenStreetMap. | |
| … | … | ||
| 41 | 41 | ||
| 42 | 42 | public class API06Node extends API06GeographicalItem implements Node | |
| 43 | 43 | { | |
| 44 | private LonLat m_lonlat = null; | ||
| 45 | private ID[] m_containingWays = null; | ||
| 46 | |||
| 47 | @Override | ||
| 48 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 49 | { | ||
| 50 | super.readExternal(in); | ||
| 51 | m_lonlat = (LonLat)in.readObject(); | ||
| 52 | m_containingWays = (ID[])in.readObject(); | ||
| 53 | } | ||
| 54 | |||
| 55 | @Override | ||
| 56 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 57 | { | ||
| 58 | super.writeExternal(out); | ||
| 59 | out.writeObject(m_lonlat); | ||
| 60 | out.writeObject(m_containingWays); | ||
| 61 | } | ||
| 62 | |||
| 44 | 63 | /** | |
| 45 | 64 | * Only for serialization. | |
| 46 | 65 | */ | |
| … | … | ||
| 71 | 71 | protected API06Node(Element a_dom, API06API a_api) | |
| 72 | 72 | { | |
| 73 | 73 | super(a_dom, a_api); | |
| 74 | |||
| 75 | m_lonlat = new LonLat(Double.parseDouble(a_dom.getAttribute("lon")), Double.parseDouble(a_dom.getAttribute("lat"))); | ||
| 74 | 76 | } | |
| 75 | 77 | ||
| 76 | 78 | @Override | |
| 77 | 79 | public LonLat getLonLat() | |
| 78 | 80 | { | |
| 79 | return new LonLat(Float.parseFloat(getDOM().getAttribute("lon")), Float.parseFloat(getDOM().getAttribute("lat"))); | ||
| 81 | return m_lonlat; | ||
| 80 | 82 | } | |
| 81 | 83 | ||
| 82 | 84 | @Override | |
| 83 | public Way[] getContainingWays() throws APIError | ||
| 85 | public ID[] getContainingWays() throws APIError | ||
| 84 | 86 | { | |
| 85 | Way[] ret = (Way[])getAPI().get("/node/"+getID()+"/ways"); | ||
| 86 | VersionedItemCache<Way> cache = getAPI().getWayFactory().getCache(); | ||
| 87 | for(Way it : ret) | ||
| 87 | if(m_containingWays == null) | ||
| 88 | 88 | { | |
| 89 | ((API06Way)it).markAsCurrent(); | ||
| 90 | cache.cacheObject(it); | ||
| 89 | Item[] ways = getAPI().get("/node/"+getID()+"/ways"); | ||
| 90 | VersionedItemCache<Way> cache = getAPI().getWayFactory().getCache(); | ||
| 91 | synchronized(this) | ||
| 92 | { | ||
| 93 | m_containingWays = new ID[ways.length]; | ||
| 94 | for(int i=0; i<ways.length; i++) | ||
| 95 | { | ||
| 96 | ((API06GeographicalItem)ways[i]).markAsCurrent(); | ||
| 97 | cache.cacheObject((Way)ways[i]); | ||
| 98 | m_containingWays[i] = ways[i].getID(); | ||
| 99 | } | ||
| 100 | } | ||
| 91 | 101 | } | |
| 92 | 102 | ||
| 93 | // FIXME: Cache this result somehow? | ||
| 94 | return ret; | ||
| 103 | return Arrays.copyOf(m_containingWays, m_containingWays.length); | ||
| 95 | 104 | } | |
| 96 | 105 | } |
|   | |||
| 31 | 31 | import org.w3c.dom.NodeList; | |
| 32 | 32 | ||
| 33 | 33 | import eu.cdauth.osm.lib.GeographicalItem; | |
| 34 | import java.io.IOException; | ||
| 35 | import java.io.ObjectInput; | ||
| 36 | import java.io.ObjectOutput; | ||
| 37 | import java.util.Arrays; | ||
| 34 | 38 | ||
| 35 | 39 | public class API06Relation extends API06GeographicalItem implements Relation | |
| 36 | 40 | { | |
| 41 | private API06RelationMember[] m_members = null; | ||
| 42 | |||
| 43 | @Override | ||
| 44 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 45 | { | ||
| 46 | super.readExternal(in); | ||
| 47 | m_members = (API06RelationMember[])in.readObject(); | ||
| 48 | } | ||
| 49 | |||
| 50 | @Override | ||
| 51 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 52 | { | ||
| 53 | super.writeExternal(out); | ||
| 54 | out.writeObject(m_members); | ||
| 55 | } | ||
| 56 | |||
| 37 | 57 | /** | |
| 38 | 58 | * Only for serialization. | |
| 39 | 59 | */ | |
| … | … | ||
| 65 | 65 | protected API06Relation(Element a_dom, API06API a_api) | |
| 66 | 66 | { | |
| 67 | 67 | super(a_dom, a_api); | |
| 68 | |||
| 69 | NodeList members = a_dom.getElementsByTagName("member"); | ||
| 70 | m_members = new API06RelationMember[members.getLength()]; | ||
| 71 | for(int i=0; i<members.getLength(); i++) | ||
| 72 | m_members[i] = new API06RelationMember((Element) members.item(i), getAPI(), getID()); | ||
| 68 | 73 | } | |
| 69 | 74 | ||
| 70 | 75 | @Override | |
| 71 | 76 | public API06RelationMember[] getMembers() | |
| 72 | 77 | { | |
| 73 | NodeList members = getDOM().getElementsByTagName("member"); | ||
| 74 | API06RelationMember[] ret = new API06RelationMember[members.getLength()]; | ||
| 75 | for(int i=0; i<members.getLength(); i++) | ||
| 76 | ret[i] = new API06RelationMember((Element) members.item(i), getAPI(), this); | ||
| 77 | return ret; | ||
| 78 | return Arrays.copyOf(m_members, m_members.length); | ||
| 78 | 79 | } | |
| 79 | 80 | ||
| 80 | 81 | /** |
|   | |||
| 58 | 58 | if(type.equals(Node.class)) | |
| 59 | 59 | isCached = (nodeCache.getObject(id) != null); | |
| 60 | 60 | else if(type.equals(Way.class)) | |
| 61 | isCached = (wayCache.getObject(id) != null); | ||
| 61 | isCached = (wayCache.getObject(id) != null); // FIXME: Download also necessary if some of the way”s member nodes are missing | ||
| 62 | 62 | else if(type.equals(Relation.class)) | |
| 63 | 63 | isCached = (relationCache.getObject(id) != null); | |
| 64 | 64 | if(!isCached) |
|   | |||
| 29 | 29 | import eu.cdauth.osm.lib.Relation; | |
| 30 | 30 | import eu.cdauth.osm.lib.RelationMember; | |
| 31 | 31 | import eu.cdauth.osm.lib.Way; | |
| 32 | import java.io.IOException; | ||
| 33 | import java.io.ObjectInput; | ||
| 34 | import java.io.ObjectOutput; | ||
| 32 | 35 | ||
| 33 | 36 | public class API06RelationMember extends API06XMLItem implements RelationMember | |
| 34 | 37 | { | |
| 35 | private Relation m_relation; // Not final because of serialization | ||
| 38 | private String m_type = null; | ||
| 39 | private ID m_referenceID = null; | ||
| 40 | private ID m_relationID = null; | ||
| 41 | private String m_role = null; | ||
| 36 | 42 | ||
| 43 | @Override | ||
| 44 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 45 | { | ||
| 46 | super.readExternal(in); | ||
| 47 | m_type = (String)in.readObject(); | ||
| 48 | m_referenceID = (ID)in.readObject(); | ||
| 49 | m_relationID = (ID)in.readObject(); | ||
| 50 | m_role = (String)in.readObject(); | ||
| 51 | } | ||
| 52 | |||
| 53 | @Override | ||
| 54 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 55 | { | ||
| 56 | super.writeExternal(out); | ||
| 57 | out.writeObject(m_type); | ||
| 58 | out.writeObject(m_referenceID); | ||
| 59 | out.writeObject(m_relationID); | ||
| 60 | out.writeObject(m_role); | ||
| 61 | } | ||
| 62 | |||
| 37 | 63 | /** | |
| 38 | 64 | * Only used for serialization. | |
| 39 | 65 | */ | |
| … | … | ||
| 68 | 68 | { | |
| 69 | 69 | } | |
| 70 | 70 | ||
| 71 | protected API06RelationMember(Element a_dom, API06API a_api, Relation a_relation) | ||
| 71 | protected API06RelationMember(Element a_dom, API06API a_api, ID a_relation) | ||
| 72 | 72 | { | |
| 73 | 73 | super(a_dom, a_api); | |
| 74 | m_relation = a_relation; | ||
| 74 | |||
| 75 | m_relationID = a_relation; | ||
| 76 | m_type = a_dom.getAttribute("type"); | ||
| 77 | m_referenceID = new ID(a_dom.getAttribute("ref")); | ||
| 78 | m_role = a_dom.getAttribute("role"); | ||
| 75 | 79 | } | |
| 76 | 80 | ||
| 77 | 81 | @Override | |
| 78 | public Relation getRelation() | ||
| 82 | public ID getRelation() | ||
| 79 | 83 | { | |
| 80 | return m_relation; | ||
| 84 | return m_relationID; | ||
| 81 | 85 | } | |
| 82 | 86 | ||
| 83 | 87 | @Override | |
| 84 | 88 | public Class<? extends GeographicalItem> getType() | |
| 85 | 89 | { | |
| 86 | String type = getDOM().getAttribute("type"); | ||
| 87 | if(type.equals("node")) | ||
| 90 | if(m_type.equals("node")) | ||
| 88 | 91 | return Node.class; | |
| 89 | else if(type.equals("way")) | ||
| 92 | else if(m_type.equals("way")) | ||
| 90 | 93 | return Way.class; | |
| 91 | else if(type.equals("relation")) | ||
| 94 | else if(m_type.equals("relation")) | ||
| 92 | 95 | return Relation.class; | |
| 93 | 96 | else | |
| 94 | throw new RuntimeException("Unknown relation member type "+type+"."); | ||
| 97 | throw new RuntimeException("Unknown relation member type "+m_type+"."); | ||
| 95 | 98 | } | |
| 96 | 99 | ||
| 97 | 100 | @Override | |
| 98 | 101 | public ID getReferenceID() | |
| 99 | 102 | { | |
| 100 | return new ID(getDOM().getAttribute("ref")); | ||
| 103 | return m_referenceID; | ||
| 101 | 104 | } | |
| 102 | 105 | ||
| 103 | 106 | @Override | |
| 104 | 107 | public String getRole() | |
| 105 | 108 | { | |
| 106 | return getDOM().getAttribute("role"); | ||
| 109 | return m_role; | ||
| 107 | 110 | } | |
| 108 | 111 | } |
|   | |||
| 31 | 31 | import eu.cdauth.osm.lib.LonLat; | |
| 32 | 32 | import eu.cdauth.osm.lib.Node; | |
| 33 | 33 | import eu.cdauth.osm.lib.Way; | |
| 34 | import java.io.IOException; | ||
| 35 | import java.io.ObjectInput; | ||
| 36 | import java.io.ObjectOutput; | ||
| 37 | import java.util.Arrays; | ||
| 34 | 38 | ||
| 35 | 39 | public class API06Way extends API06GeographicalItem implements Way | |
| 36 | 40 | { | |
| 41 | private ID[] m_members = null; | ||
| 42 | |||
| 43 | @Override | ||
| 44 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 45 | { | ||
| 46 | super.readExternal(in); | ||
| 47 | m_members = (ID[])in.readObject(); | ||
| 48 | } | ||
| 49 | |||
| 50 | @Override | ||
| 51 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 52 | { | ||
| 53 | super.writeExternal(out); | ||
| 54 | out.writeObject(m_members); | ||
| 55 | } | ||
| 56 | |||
| 37 | 57 | /** | |
| 38 | 58 | * Only for serialization. | |
| 39 | 59 | */ | |
| … | … | ||
| 65 | 65 | protected API06Way(Element a_dom, API06API a_api) | |
| 66 | 66 | { | |
| 67 | 67 | super(a_dom, a_api); | |
| 68 | |||
| 69 | NodeList members = a_dom.getElementsByTagName("nd"); | ||
| 70 | m_members = new ID[members.getLength()]; | ||
| 71 | for(int i=0; i<members.getLength(); i++) | ||
| 72 | m_members[i] = new ID(((Element)members.item(i)).getAttribute("ref")); | ||
| 68 | 73 | } | |
| 69 | 74 | ||
| 70 | 75 | /** | |
| … | … | ||
| 79 | 79 | @Override | |
| 80 | 80 | public ID[] getMembers() | |
| 81 | 81 | { | |
| 82 | NodeList members = getDOM().getElementsByTagName("nd"); | ||
| 83 | ID[] ret = new ID[members.getLength()]; | ||
| 84 | for(int i=0; i<members.getLength(); i++) | ||
| 85 | ret[i] = new ID(((Element)members.item(i)).getAttribute("ref")); | ||
| 86 | return ret; | ||
| 82 | return Arrays.copyOf(m_members, m_members.length); | ||
| 87 | 83 | } | |
| 88 | |||
| 84 | |||
| 85 | @Override | ||
| 89 | 86 | public Node[] getMemberNodes(Date a_date) throws APIError | |
| 90 | 87 | { | |
| 91 | 88 | if(a_date != null) | |
| 92 | getAPI().getWayFactory().downloadFull(new ID(getDOM().getAttribute("id"))); | ||
| 89 | getAPI().getWayFactory().downloadFull(getID()); | ||
| 93 | 90 | ID[] members = getMembers(); | |
| 94 | 91 | Node[] ret = new Node[members.length]; | |
| 95 | 92 | for(int i=0; i<members.length; i++) |
|   | |||
| 1 | /* | ||
| 2 | Copyright © 2010 Candid Dauth | ||
| 3 | |||
| 4 | Permission is hereby granted, free of charge, to any person obtaining | ||
| 5 | a copy of this software and associated documentation files (the “Software”), | ||
| 6 | to deal in the Software without restriction, including without limitation | ||
| 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | and/or sell copies of the Software, and to permit persons to whom the Software | ||
| 9 | is furnished to do so, subject to the following conditions: | ||
| 10 | |||
| 11 | The above copyright notice and this permission notice shall be included in all | ||
| 12 | copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
| 16 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 17 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 18 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
| 19 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 20 | */ | ||
| 21 | |||
| 22 | package eu.cdauth.osm.lib.api06; | ||
| 23 | |||
| 24 | import org.w3c.dom.Element; | ||
| 25 | import org.w3c.dom.bootstrap.DOMImplementationRegistry; | ||
| 26 | import org.w3c.dom.ls.DOMImplementationLS; | ||
| 27 | import org.w3c.dom.ls.LSInput; | ||
| 28 | import org.w3c.dom.ls.LSParser; | ||
| 29 | import org.w3c.dom.ls.LSSerializer; | ||
| 30 | |||
| 31 | import java.io.*; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * Abstract class for all objects whose information is saved in an XML DOM element. | ||
| 35 | */ | ||
| 36 | abstract public class API06XMLItem implements Externalizable | ||
| 37 | { | ||
| 38 | private transient API06API m_api; | ||
| 39 | |||
| 40 | @Override | ||
| 41 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException | ||
| 42 | { | ||
| 43 | } | ||
| 44 | |||
| 45 | @Override | ||
| 46 | public void writeExternal(ObjectOutput out) throws IOException | ||
| 47 | { | ||
| 48 | } | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Only for serialization. | ||
| 52 | */ | ||
| 53 | @Deprecated | ||
| 54 | public API06XMLItem() | ||
| 55 | { | ||
| 56 | } | ||
| 57 | |||
| 58 | /** | ||
| 59 | * @param a_dom The DOM element. | ||
| 60 | * @param a_api The API that creates this object. | ||
| 61 | */ | ||
| 62 | |||
| 63 | protected API06XMLItem(Element a_dom, API06API a_api) | ||
| 64 | { | ||
| 65 | m_api = a_api; | ||
| 66 | } | ||
| 67 | |||
| 68 | protected void setAPI(API06API a_api) | ||
| 69 | { | ||
| 70 | m_api = a_api; | ||
| 71 | } | ||
| 72 | |||
| 73 | protected API06API getAPI() | ||
| 74 | { | ||
| 75 | return m_api; | ||
| 76 | } | ||
| 77 | } |
|   | |||
| 1 | /* | ||
| 2 | Copyright © 2010 Candid Dauth | ||
| 3 | |||
| 4 | Permission is hereby granted, free of charge, to any person obtaining | ||
| 5 | a copy of this software and associated documentation files (the “Software”), | ||
| 6 | to deal in the Software without restriction, including without limitation | ||
| 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | and/or sell copies of the Software, and to permit persons to whom the Software | ||
| 9 | is furnished to do so, subject to the following conditions: | ||
| 10 | |||
| 11 | The above copyright notice and this permission notice shall be included in all | ||
| 12 | copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
| 16 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 17 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 18 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
| 19 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 20 | */ | ||
| 21 | |||
| 22 | package eu.cdauth.osm.lib.api06; | ||
| 23 | |||
| 24 | import java.io.BufferedOutputStream; | ||
| 25 | import java.io.ByteArrayInputStream; | ||
| 26 | import java.io.ByteArrayOutputStream; | ||
| 27 | import java.io.ObjectInputStream; | ||
| 28 | import java.io.ObjectOutputStream; | ||
| 29 | import java.io.Serializable; | ||
| 30 | import org.junit.Test; | ||
| 31 | import static org.junit.Assert.*; | ||
| 32 | |||
| 33 | public class SerializationTest | ||
| 34 | { | ||
| 35 | public <T extends Serializable> T reconstruct(T a_object) throws Exception | ||
| 36 | { | ||
| 37 | ByteArrayOutputStream ser = new ByteArrayOutputStream(); | ||
| 38 | BufferedOutputStream ser2 = new BufferedOutputStream(ser); | ||
| 39 | ObjectOutputStream ser3 = new ObjectOutputStream(ser2); | ||
| 40 | ser3.writeObject(a_object); | ||
| 41 | ser3.close(); | ||
| 42 | |||
| 43 | ByteArrayInputStream ser4 = new ByteArrayInputStream(ser.toByteArray()); | ||
| 44 | ObjectInputStream ser5 = new ObjectInputStream(ser4); | ||
| 45 | T ret = (T) ser5.readObject(); | ||
| 46 | ser5.close(); | ||
| 47 | |||
| 48 | return ret; | ||
| 49 | } | ||
| 50 | |||
| 51 | @Test | ||
| 52 | public void node() throws Exception | ||
| 53 | { | ||
| 54 | API06Node node = XMLReadTest.makeNode(); | ||
| 55 | API06Node clone = reconstruct(node); | ||
| 56 | |||
| 57 | assertEquals(node, clone); | ||
| 58 | assertEquals(node.getID(), clone.getID()); | ||
| 59 | assertEquals(node.getLonLat(), clone.getLonLat()); | ||
| 60 | assertEquals(node.getVersion(), clone.getVersion()); | ||
| 61 | assertEquals(node.getChangeset(), clone.getChangeset()); | ||
| 62 | assertEquals(node.getTimestamp(), clone.getTimestamp()); | ||
| 63 | assertEquals(node.getTags(), clone.getTags()); | ||
| 64 | } | ||
| 65 | } |
|   | |||
| 1 | /* | ||
| 2 | Copyright © 2010 Candid Dauth | ||
| 3 | |||
| 4 | Permission is hereby granted, free of charge, to any person obtaining | ||
| 5 | a copy of this software and associated documentation files (the “Software”), | ||
| 6 | to deal in the Software without restriction, including without limitation | ||
| 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | and/or sell copies of the Software, and to permit persons to whom the Software | ||
| 9 | is furnished to do so, subject to the following conditions: | ||
| 10 | |||
| 11 | The above copyright notice and this permission notice shall be included in all | ||
| 12 | copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | ||
| 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
| 16 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
| 17 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 18 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
| 19 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 20 | */ | ||
| 21 | |||
| 22 | package eu.cdauth.osm.lib.api06; | ||
| 23 | |||
| 24 | import eu.cdauth.osm.lib.Item; | ||
| 25 | import java.io.ByteArrayInputStream; | ||
| 26 | import java.io.IOException; | ||
| 27 | import java.util.List; | ||
| 28 | import javax.xml.parsers.DocumentBuilderFactory; | ||
| 29 | import javax.xml.parsers.ParserConfigurationException; | ||
| 30 | import org.junit.Test; | ||
| 31 | import static org.junit.Assert.*; | ||
| 32 | import org.w3c.dom.Document; | ||
| 33 | import org.w3c.dom.Element; | ||
| 34 | import org.w3c.dom.NodeList; | ||
| 35 | import org.xml.sax.SAXException; | ||
| 36 | |||
| 37 | public class XMLReadTest | ||
| 38 | { | ||
| 39 | public static final API06API sm_api = new API06API(); | ||
| 40 | |||
| 41 | public static API06Item makeItem(String a_xml) throws Exception | ||
| 42 | { | ||
| 43 | Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(a_xml.getBytes("UTF-8"))); | ||
| 44 | Element root = null; | ||
| 45 | NodeList nodes = dom.getChildNodes(); | ||
| 46 | for(int i=0; i<nodes.getLength(); i++) | ||
| 47 | { | ||
| 48 | if(nodes.item(i).getNodeType() != org.w3c.dom.Node.ELEMENT_NODE) | ||
| 49 | continue; | ||
| 50 | root = (Element) nodes.item(i); | ||
| 51 | break; | ||
| 52 | } | ||
| 53 | |||
| 54 | if(root == null) | ||
| 55 | throw new IOException("No root element."); | ||
| 56 | |||
| 57 | List<Item> items = sm_api.makeObjects(root); | ||
| 58 | if(items.size() < 1) | ||
| 59 | throw new IOException("No items."); | ||
| 60 | |||
| 61 | return (API06Item)items.get(0); | ||
| 62 | } | ||
| 63 | |||
| 64 | public static API06Node makeNode() throws Exception | ||
| 65 | { | ||
| 66 | return (API06Node)makeItem("<osm version=\"0.6\" generator=\"OpenStreetMap server\">" + | ||
| 67 | "<node id=\"123456\" lat=\"51.2153688\" lon=\"4.089274\" version=\"8\" changeset=\"359445\" user=\"Benjamiini\" uid=\"65172\" visible=\"true\" timestamp=\"2008-12-13T15:05:11Z\">" + | ||
| 68 | "<tag k=\"tourism\" v=\"camp_site\"/>" + | ||
| 69 | "<tag k=\"name\" v=\"Bariş Camping\"/>" + | ||
| 70 | "</node>" + | ||
| 71 | "</osm>"); | ||
| 72 | } | ||
| 73 | |||
| 74 | @Test | ||
| 75 | public void node() throws Exception | ||
| 76 | { | ||
| 77 | API06Node node = makeNode(); | ||
| 78 | |||
| 79 | assertEquals(node.getID().asLong().longValue(), 123456L); | ||
| 80 | assertEquals(node.getLonLat().getLon(), 4.089274D, 0.00000005D); | ||
| 81 | assertEquals(node.getLonLat().getLat(), 51.2153688D, 0.00000005D); | ||
| 82 | assertEquals(node.getVersion().asLong().longValue(), 8L); | ||
| 83 | assertEquals(node.getChangeset().asLong().longValue(), 359445L); | ||
| 84 | assertEquals(node.getTimestamp().getTime(), 1229180711000L); | ||
| 85 | assertEquals(node.getTags().size(), 2); | ||
| 86 | assertEquals(node.getTag("tourism"), "camp_site"); | ||
| 87 | assertEquals(node.getTag("name"), "Bariş Camping"); | ||
| 88 | } | ||
| 89 | } |
|   | |||
| 14 | 14 | public interface GeographicalItem extends Item | |
| 15 | 15 | { | |
| 16 | 16 | /** | |
| 17 | * Returns all relations that the <strong>current</strong> version of this object is currently contained in. | ||
| 17 | * Returns the IDs all relations that the <strong>current</strong> version of this object is currently contained in. | ||
| 18 | 18 | * Relations can only contain geographical objects. | |
| 19 | * @return The relations that contain this object. | ||
| 19 | * @return The IDs of the relations that contain this object. | ||
| 20 | 20 | * @throws APIError There was an error fetching the relations. | |
| 21 | 21 | */ | |
| 22 | public Relation[] getContainingRelations() throws APIError; | ||
| 22 | public ID[] getContainingRelations() throws APIError; | ||
| 23 | 23 | } |
|   | |||
| 38 | 38 | /** | |
| 39 | 39 | * How many entries may be in the database cache? | |
| 40 | 40 | */ | |
| 41 | public static final int MAX_DATABASE_VALUES = 5000; | ||
| 41 | public static final int MAX_DATABASE_VALUES = 50000; | ||
| 42 | 42 | /** | |
| 43 | 43 | * How old may the entries in the database cache be at most? (seconds) | |
| 44 | 44 | */ | |
| … | … | ||
| 159 | 159 | { | |
| 160 | 160 | synchronized(m_cacheTimes) | |
| 161 | 161 | { | |
| 162 | m_cache.put(id, a_object); | ||
| 162 | T old = m_cache.get(id); | ||
| 163 | if(old == null || !old.equals(a_object)) // Prevent additionally downloaded data (for example the content of a changeset) from being lost. | ||
| 164 | m_cache.put(id, a_object); | ||
| 163 | 165 | m_cacheTimes.put(id, System.currentTimeMillis()); | |
| 164 | 166 | } | |
| 165 | 167 | } | |
| … | … | ||
| 197 | 197 | /** | |
| 198 | 198 | * Clean up entries from the memory cache that exceed {@link #MAX_CACHED_VALUES} or {@link #MAX_AGE}. If a database | |
| 199 | 199 | * cache is used, the entries are moved there. | |
| 200 | * @param a_completely If set to true, the memory cache will be cleared completely, not just up to {@link #MAX_CACHED_VALUES} (useful at shutdown) | ||
| 200 | 201 | */ | |
| 201 | protected void cleanUpMemory() | ||
| 202 | protected void cleanUpMemory(boolean a_completely) | ||
| 202 | 203 | { | |
| 203 | 204 | String persistenceID = getPersistenceID(); | |
| 204 | 205 | Connection conn = null; | |
| … | … | ||
| 229 | 229 | break; | |
| 230 | 230 | ID oldest = m_cacheTimes.firstKey(); | |
| 231 | 231 | long oldestTime = m_cacheTimes.get(oldest); | |
| 232 | if(System.currentTimeMillis()-oldestTime <= MAX_AGE*1000 && m_cacheTimes.size() <= MAX_CACHED_VALUES) | ||
| 232 | if(!a_completely && System.currentTimeMillis()-oldestTime <= MAX_AGE*1000 && m_cacheTimes.size() <= MAX_CACHED_VALUES) | ||
| 233 | 233 | break; | |
| 234 | 234 | m_cacheTimes.remove(oldest); | |
| 235 | 235 | item = m_cache.remove(oldest); | |
| … | … | ||
| 395 | 395 | ||
| 396 | 396 | /** | |
| 397 | 397 | * Runs {@link #cleanUpMemory()} and {@link #cleanUpDatabase()} on all instances of this class. | |
| 398 | * @param a_completely If set to true, the memory cache is cleared completely instead of just to {@link #MAX_CACHED_VALUES}. | ||
| 398 | 399 | */ | |
| 399 | public static void cleanUpAll() | ||
| 400 | public static void cleanUpAll(boolean a_completely) | ||
| 400 | 401 | { | |
| 401 | 402 | ItemCache<? extends Item>[] instances; | |
| 402 | 403 | synchronized(sm_instances) | |
| … | … | ||
| 416 | 416 | number++; | |
| 417 | 417 | try | |
| 418 | 418 | { | |
| 419 | instance.cleanUpMemory(); | ||
| 419 | instance.cleanUpMemory(a_completely); | ||
| 420 | 420 | instance.cleanUpDatabase(); | |
| 421 | 421 | } | |
| 422 | 422 | catch(Exception e) |
|   | |||
| 58 | 58 | ||
| 59 | 59 | /** | |
| 60 | 60 | * Two LonLat objects are equal if their coordinates are the same. | |
| 61 | * The OpenStreetMap database saves 7 decimals for each coordinate. If lower decimals differ, this is a result of computation errors | ||
| 62 | * and is ignored. | ||
| 61 | 63 | * | |
| 62 | 64 | * <p>{@inheritDoc} | |
| 63 | 65 | */ | |
| … | … | ||
| 71 | 71 | if(a_other instanceof LonLat) | |
| 72 | 72 | { | |
| 73 | 73 | LonLat other = (LonLat) a_other; | |
| 74 | return (getLon() == other.getLon() && getLat() == other.getLat()); | ||
| 74 | return (Math.abs(getLon()-other.getLon()) < 0.00000005D && Math.abs(getLat()-other.getLat()) < 0.00000005D); | ||
| 75 | 75 | } | |
| 76 | 76 | return false; | |
| 77 | 77 | } |
|   | |||
| 19 | 19 | public LonLat getLonLat(); | |
| 20 | 20 | ||
| 21 | 21 | /** | |
| 22 | * Returns all ways that currently contain the <strong>current</strong> version of this node. | ||
| 23 | * @return An array of ways that currently contain this node. | ||
| 22 | * Returns the ID of all ways that currently contain the <strong>current</strong> version of this node. | ||
| 23 | * @return An array of the IDs of all ways that currently contain this node. | ||
| 24 | 24 | * @throws APIError The ways could not be fetched. | |
| 25 | 25 | */ | |
| 26 | public Way[] getContainingWays() throws APIError; | ||
| 26 | public ID[] getContainingWays() throws APIError; | ||
| 27 | 27 | } |
|   | |||
| 21 | 21 | public interface RelationMember extends Serializable | |
| 22 | 22 | { | |
| 23 | 23 | /** | |
| 24 | * Returns the corresponding {@link Relation} that this member belongs to. | ||
| 25 | * @return The relation that contains this member. | ||
| 24 | * Returns the corresponding {@link Relation} ID that this member belongs to. | ||
| 25 | * @return The ID of the relation that contains this member. | ||
| 26 | 26 | */ | |
| 27 | public Relation getRelation(); | ||
| 27 | public ID getRelation(); | ||
| 28 | 28 | ||
| 29 | 29 | /** | |
| 30 | 30 | * Returns the type of the {@link GeographicalItem} that this member refers to. |
|   | |||
| 205 | 205 | } | |
| 206 | 206 | ||
| 207 | 207 | @Override | |
| 208 | protected void cleanUpMemory() | ||
| 208 | protected void cleanUpMemory(boolean a_completely) | ||
| 209 | 209 | { | |
| 210 | super.cleanUpMemory(); | ||
| 210 | super.cleanUpMemory(a_completely); | ||
| 211 | 211 | ||
| 212 | 212 | String persistenceID = getPersistenceID(); | |
| 213 | 213 | Connection conn = null; | |
| … | … | ||
| 237 | 237 | break; | |
| 238 | 238 | ID oldest = m_historyTimes.firstKey(); | |
| 239 | 239 | long oldestTime = m_historyTimes.get(oldest); | |
| 240 | if(System.currentTimeMillis()-oldestTime <= MAX_AGE*1000 && m_historyTimes.size() <= MAX_CACHED_VALUES) | ||
| 240 | if(!a_completely && System.currentTimeMillis()-oldestTime <= MAX_AGE*1000 && m_historyTimes.size() <= MAX_CACHED_VALUES) | ||
| 241 | 241 | break; | |
| 242 | 242 | id = oldest; | |
| 243 | 243 | m_historyTimes.remove(oldest); |
pom.xml
(1 / 1)
|   | |||
| 120 | 120 | <plugin> | |
| 121 | 121 | <groupId>org.xnap.commons</groupId> | |
| 122 | 122 | <artifactId>maven-gettext-plugin</artifactId> | |
| 123 | <version>1.2.0</version> | ||
| 123 | <version>1.2.1</version> | ||
| 124 | 124 | <executions> | |
| 125 | 125 | <execution> | |
| 126 | 126 | <phase>compile</phase> |
|   | |||
| 68 | 68 | private final HttpServletResponse m_resp; | |
| 69 | 69 | ||
| 70 | 70 | private static API06API sm_api = null; | |
| 71 | private static Timer sm_apiCleanUp = null; | ||
| 71 | private static Thread sm_apiCleanUp = null; | ||
| 72 | |||
| 73 | private static int sm_servletsRunning = 0; | ||
| 72 | 74 | ||
| 75 | public synchronized static void servletStart() | ||
| 76 | { | ||
| 77 | if(sm_servletsRunning++ == 0) | ||
| 78 | { | ||
| 79 | Logger.getLogger(GUI.class.getName()).info("Starting cache cleanup thread."); | ||
| 80 | sm_apiCleanUp = new Thread("osmrmhv cache cleanup") { | ||
| 81 | @Override public void run() { | ||
| 82 | while(true) | ||
| 83 | { | ||
| 84 | try { | ||
| 85 | Thread.sleep(60000); | ||
| 86 | } catch(InterruptedException e) { | ||
| 87 | break; | ||
| 88 | } | ||
| 89 | try { | ||
| 90 | ItemCache.cleanUpAll(false); | ||
| 91 | } catch(Exception e) { | ||
| 92 | Logger.getLogger(GUI.class.getName()).log(Level.WARNING, "Unexpected exception.", e); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | } | ||
| 96 | }; | ||
| 97 | sm_apiCleanUp.start(); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | public synchronized static void servletStop() | ||
| 102 | { | ||
| 103 | if(--sm_servletsRunning == 0) | ||
| 104 | { | ||
| 105 | Logger.getLogger(GUI.class.getName()).info("Stopping cache cleanup thread, completely clearing memory."); | ||
| 106 | sm_apiCleanUp.interrupt(); | ||
| 107 | sm_apiCleanUp = null; | ||
| 108 | ItemCache.cleanUpAll(true); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 73 | 112 | /** | |
| 74 | 113 | * Returns an {@link eu.cdauth.osm.lib.API} object to use. | |
| 75 | 114 | * @return The API object to use. | |
| … | … | ||
| 132 | 132 | Logger.getLogger(GUI.class.getName()).info("Using API with database cache."); | |
| 133 | 133 | sm_api = new eu.cdauth.osm.lib.api06.API06API(ds); | |
| 134 | 134 | } | |
| 135 | |||
| 136 | new Thread("osmrmhv cache cleanup") { | ||
| 137 | @Override public void run() { | ||
| 138 | while(true) | ||
| 139 | { | ||
| 140 | try { | ||
| 141 | Thread.sleep(60000); | ||
| 142 | } catch(InterruptedException e) { | ||
| 143 | break; | ||
| 144 | } | ||
| 145 | try { | ||
| 146 | ItemCache.cleanUpAll(); | ||
| 147 | } catch(Exception e) { | ||
| 148 | Logger.getLogger(GUI.class.getName()).log(Level.WARNING, "Unexpected exception.", e); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | ||
| 152 | }.start(); | ||
| 153 | 135 | } | |
| 154 | 136 | return sm_api; | |
| 155 | 137 | } |
|   | |||
| 237 | 237 | }*/ | |
| 238 | 238 | ||
| 239 | 239 | // Second guess: Current parent nodes of the node | |
| 240 | for(Way obj : node.getContainingWays()) | ||
| 240 | for(Way obj : a_api.getWayFactory().fetch(node.getContainingWays()).values()) | ||
| 241 | 241 | { | |
| 242 | 242 | if(waysChanged.containsKey(obj.getID())) | |
| 243 | 243 | continue; |
|   | |||
| 52 | 52 | return a_other.changes.compareTo(changes); | |
| 53 | 53 | } | |
| 54 | 54 | } | |
| 55 | |||
| 56 | public void jspInit() | ||
| 57 | { | ||
| 58 | GUI.servletStart(); | ||
| 59 | } | ||
| 60 | |||
| 61 | public void jspDestroy() | ||
| 62 | { | ||
| 63 | GUI.servletStop(); | ||
| 64 | } | ||
| 55 | 65 | %> | |
| 56 | 66 | <% | |
| 57 | 67 | if(request.getParameter("id") == null) |
|   | |||
| 24 | 24 | <%@page contentType="text/html; charset=UTF-8" buffer="none" session="false"%> | |
| 25 | 25 | <%! | |
| 26 | 26 | protected static final API api = GUI.getAPI(); | |
| 27 | |||
| 28 | public void jspInit() | ||
| 29 | { | ||
| 30 | GUI.servletStart(); | ||
| 31 | } | ||
| 32 | |||
| 33 | public void jspDestroy() | ||
| 34 | { | ||
| 35 | GUI.servletStop(); | ||
| 36 | } | ||
| 27 | 37 | %> | |
| 28 | 38 | <% | |
| 29 | 39 | if(request.getParameter("id") == null) |
|   | |||
| 23 | 23 | <%@page contentType="text/html; charset=UTF-8" buffer="none" session="false"%> | |
| 24 | 24 | <%! | |
| 25 | 25 | protected static final API api = GUI.getAPI(); | |
| 26 | |||
| 27 | public void jspInit() | ||
| 28 | { | ||
| 29 | GUI.servletStart(); | ||
| 30 | } | ||
| 31 | |||
| 32 | public void jspDestroy() | ||
| 33 | { | ||
| 34 | GUI.servletStop(); | ||
| 35 | } | ||
| 26 | 36 | %> | |
| 27 | 37 | <% | |
| 28 | 38 | GUI gui = new GUI(request, response); |
|   | |||
| 23 | 23 | <%@page contentType="text/xml; charset=UTF-8" buffer="none" session="false"%> | |
| 24 | 24 | <%! | |
| 25 | 25 | private static API api = GUI.getAPI(); | |
| 26 | |||
| 27 | public void jspInit() | ||
| 28 | { | ||
| 29 | GUI.servletStart(); | ||
| 30 | } | ||
| 31 | |||
| 32 | public void jspDestroy() | ||
| 33 | { | ||
| 34 | GUI.servletStop(); | ||
| 35 | } | ||
| 26 | 36 | %> | |
| 27 | 37 | <% | |
| 28 | 38 | response.setHeader("Content-disposition", "attachment; filename=route.gpx"); |
|   | |||
| 23 | 23 | <%@page contentType="text/html; charset=UTF-8" buffer="none" session="false"%> | |
| 24 | 24 | <%! | |
| 25 | 25 | protected static final API api = GUI.getAPI(); | |
| 26 | |||
| 27 | public void jspInit() | ||
| 28 | { | ||
| 29 | GUI.servletStart(); | ||
| 30 | } | ||
| 31 | |||
| 32 | public void jspDestroy() | ||
| 33 | { | ||
| 34 | GUI.servletStop(); | ||
| 35 | } | ||
| 26 | 36 | %> | |
| 27 | 37 | <% | |
| 28 | 38 | GUI gui = new GUI(request, response); |
|   | |||
| 24 | 24 | <%@page contentType="text/html; charset=UTF-8" buffer="none" session="false"%> | |
| 25 | 25 | <%! | |
| 26 | 26 | private static final API api = GUI.getAPI(); | |
| 27 | |||
| 28 | public void jspInit() | ||
| 29 | { | ||
| 30 | GUI.servletStart(); | ||
| 31 | } | ||
| 32 | |||
| 33 | public void jspDestroy() | ||
| 34 | { | ||
| 35 | GUI.servletStop(); | ||
| 36 | } | ||
| 27 | 37 | %> | |
| 28 | 38 | <% | |
| 29 | 39 | if(request.getParameter("id") == null) | |
| … | … | ||
| 257 | 257 | <dt><%=htmlspecialchars(gui._("Parent relations"))%></dt> | |
| 258 | 258 | <dd><ul> | |
| 259 | 259 | <% | |
| 260 | Relation[] parentRelations = relation.getContainingRelations(); | ||
| 261 | for(Relation parentRelation : parentRelations) | ||
| 260 | Map<ID,Relation> parentRelations = api.getRelationFactory().fetch(relation.getContainingRelations()); | ||
| 261 | for(Map.Entry<ID,Relation> parentRelation : parentRelations.entrySet()) | ||
| 262 | 262 | { | |
| 263 | 263 | %> | |
| 264 | <li><a href="?id=<%=htmlspecialchars(urlencode(parentRelation.getID().toString()))%>"><%=htmlspecialchars(parentRelation.getID().toString())%> (<%=htmlspecialchars(parentRelation.getTag("name"))%>)</a></li> | ||
| 264 | <li><a href="?id=<%=htmlspecialchars(urlencode(parentRelation.getKey().toString()))%>"><%=htmlspecialchars(parentRelation.getKey().toString())%> (<%=htmlspecialchars(parentRelation.getValue().getTag("name"))%>)</a></li> | ||
| 265 | 265 | <% | |
| 266 | 266 | } | |
| 267 | 267 | %> |

