// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.xml.v0_6.impl; import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer; import org.openstreetmap.osmosis.core.domain.common.TimestampContainer; import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData; import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser; import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember; import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.task.v0_6.Sink; import org.openstreetmap.osmosis.xml.common.BaseElementProcessor; import org.openstreetmap.osmosis.xml.common.ElementProcessor; import org.xml.sax.Attributes; import org.openstreetmap.osmosis.core.OsmosisRuntimeException; /** * Provides an element processor implementation for a relation. * * @author Brett Henderson */ public class RelationElementProcessor extends EntityElementProcessor implements TagListener, RelationMemberListener { private static final String ELEMENT_NAME_TAG = "tag"; private static final String ELEMENT_NAME_MEMBER = "member"; private static final String ATTRIBUTE_NAME_ID = "id"; private static final String ATTRIBUTE_NAME_TIMESTAMP = "timestamp"; private static final String ATTRIBUTE_NAME_USER = "user"; private static final String ATTRIBUTE_NAME_USERID = "uid"; private static final String ATTRIBUTE_NAME_CHANGESET_ID = "changeset"; private static final String ATTRIBUTE_NAME_VERSION = "version"; private TagElementProcessor tagElementProcessor; private RelationMemberElementProcessor relationMemberElementProcessor; private Relation relation; /** * Creates a new instance. * * @param parentProcessor * The parent of this element processor. * @param sink * The sink for receiving processed data. * @param enableDateParsing * If true, dates will be parsed from xml data, else the current * date will be used thus saving parsing time. */ public RelationElementProcessor(BaseElementProcessor parentProcessor, Sink sink, boolean enableDateParsing) { super(parentProcessor, sink, enableDateParsing); tagElementProcessor = new TagElementProcessor(this, this); relationMemberElementProcessor = new RelationMemberElementProcessor(this, this); } /** * {@inheritDoc} */ public void begin(Attributes attributes) { long id; String sversion; int version; TimestampContainer timestampContainer; String rawUserId; String rawUserName; OsmUser user; long changesetId; id = Long.parseLong(attributes.getValue(ATTRIBUTE_NAME_ID)); sversion = attributes.getValue(ATTRIBUTE_NAME_VERSION); if (sversion == null) { throw new OsmosisRuntimeException("Relation " + id + " does not have a version attribute as OSM 0.6 are required to have. Is this a 0.5 file?"); } else { version = Integer.parseInt(sversion); } timestampContainer = createTimestampContainer(attributes.getValue(ATTRIBUTE_NAME_TIMESTAMP)); rawUserId = attributes.getValue(ATTRIBUTE_NAME_USERID); rawUserName = attributes.getValue(ATTRIBUTE_NAME_USER); changesetId = buildChangesetId(attributes.getValue(ATTRIBUTE_NAME_CHANGESET_ID)); user = buildUser(rawUserId, rawUserName); relation = new Relation(new CommonEntityData(id, version, timestampContainer, user, changesetId)); } /** * Retrieves the appropriate child element processor for the newly * encountered nested element. * * @param uri * The element uri. * @param localName * The element localName. * @param qName * The element qName. * @return The appropriate element processor for the nested element. */ @Override public ElementProcessor getChild(String uri, String localName, String qName) { if (ELEMENT_NAME_MEMBER.equals(qName)) { return relationMemberElementProcessor; } else if (ELEMENT_NAME_TAG.equals(qName)) { return tagElementProcessor; } return super.getChild(uri, localName, qName); } /** * {@inheritDoc} */ public void end() { getSink().process(new RelationContainer(relation)); } /** * This is called by child element processors when a tag object is * encountered. * * @param tag * The tag to be processed. */ public void processTag(Tag tag) { relation.getTags().add(tag); } /** * This is called by child element processors when a way node object is * encountered. * * @param relationMember * The wayNode to be processed. */ public void processRelationMember(RelationMember relationMember) { relation.getMembers().add(relationMember); } }