Author: desruisseaux Date: Thu Feb 15 11:17:57 2018 New Revision: 1824296 URL: http://svn.apache.org/viewvc?rev=1824296&view=rev Log: Bug fix in the tracking of QNames in 'FilteredReader.outerElements' (was using wrong namespace).
Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java Modified: sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java?rev=1824296&r1=1824295&r2=1824296&view=diff ============================================================================== --- sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java [UTF-8] (original) +++ sis/branches/ISO-19115-3/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationTest.java [UTF-8] Thu Feb 15 11:17:57 2018 @@ -278,7 +278,7 @@ public final strictfp class DefaultCitat final CitationDate date = getSingleton(c.getDates()); assertEquals("date", date.getDate(), TestUtilities.date("2015-10-17 00:00:00")); - assertEquals("dateType", date.getDateType(), DateType.ADOPTED); + assertEquals("dateType", DateType.ADOPTED, date.getDateType()); assertEquals("presentationForm", PresentationForm.PHYSICAL_OBJECT, getSingleton(c.getPresentationForms())); final Iterator<Responsibility> it = c.getCitedResponsibleParties().iterator(); Modified: sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java?rev=1824296&r1=1824295&r2=1824296&view=diff ============================================================================== --- sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java [UTF-8] (original) +++ sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredEvent.java [UTF-8] Thu Feb 15 11:17:57 2018 @@ -287,7 +287,6 @@ abstract class FilteredEvent<E extends X name(out.append('<')); final int n = attributes.size(); for (int i=0; i<n; i++) { - if (i != 0) out.append(' '); Attr.castOrWrap(attributes.get(i)).write(out); } out.append('>'); Modified: sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java URL: http://svn.apache.org/viewvc/sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java?rev=1824296&r1=1824295&r2=1824296&view=diff ============================================================================== --- sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java [UTF-8] (original) +++ sis/branches/ISO-19115-3/core/sis-utility/src/main/java/org/apache/sis/xml/FilteredReader.java [UTF-8] Thu Feb 15 11:17:57 2018 @@ -233,6 +233,14 @@ final class FilteredReader extends Filte private final Map<String,String> prefixes; /** + * The next event to return after a call to {@link #peek()}. This is used for avoiding to recompute + * the same object many times when {@link #peek()} is invoked before a call to {@link #nextEvent()}. + * This is also required for avoiding to duplicate additions and removals of elements in the + * {@link #outerElements} list. + */ + private XMLEvent nextEvent; + + /** * Creates a new filter for the given version of the standards. */ FilteredReader(final XMLEventReader in, final FilterVersion version) { @@ -243,19 +251,33 @@ final class FilteredReader extends Filte } /** + * Returns {@code true} if the given {@code wrapper} is a wrapper for the given {@code event}. + * This method is used for assertions only. + */ + private static boolean isWrapper(final XMLEvent event, final XMLEvent wrapper) { + return (event == wrapper) || (wrapper instanceof FilteredEvent && ((FilteredEvent) wrapper).event == event); + } + + /** * Checks if there are more events. */ @Override public boolean hasNext() { - return in.hasNext(); + return (nextEvent != null) || in.hasNext(); } /** - * Check the next XMLEvent without reading it from the stream. + * Checks the next {@code XMLEvent} without removing it from the stream. */ @Override public XMLEvent peek() throws XMLStreamException { - return convert(in.peek(), false); + if (nextEvent == null) { + final XMLEvent event = in.peek(); + if (event != null) { + nextEvent = convert(event); + } + } + return nextEvent; } /** @@ -263,7 +285,14 @@ final class FilteredReader extends Filte */ @Override public Object next() { - return convert((XMLEvent) in.next(), true); + final XMLEvent event = (XMLEvent) in.next(); + final XMLEvent next = nextEvent; + if (next != null) { + nextEvent = null; + assert isWrapper(event, next) : event; + return next; + } + return convert(event); } /** @@ -271,7 +300,14 @@ final class FilteredReader extends Filte */ @Override public XMLEvent nextEvent() throws XMLStreamException { - return convert(in.nextEvent(), true); + final XMLEvent event = in.nextEvent(); + final XMLEvent next = nextEvent; + if (next != null) { + nextEvent = null; + assert isWrapper(event, next) : event; + return next; + } + return convert(event); } /** @@ -279,19 +315,32 @@ final class FilteredReader extends Filte */ @Override public XMLEvent nextTag() throws XMLStreamException { - return convert(in.nextTag(), true); + final XMLEvent event = in.nextTag(); + final XMLEvent next = nextEvent; + if (next != null) { + nextEvent = null; + switch (event.getEventType()) { + case START_ELEMENT: + case END_ELEMENT: { + assert isWrapper(event, next) : event; + return event; + } + } + } + return convert(event); } /** * Keeps trace of XML elements opened up to this point and imports the given event. * This method replaces the namespaces used in XML document by the namespace used by JAXB annotations. + * It is caller's responsibility to ensure that this method is invoked exactly once for each element, + * or at least for each {@code START_ELEMENT} and {@code END_ELEMENT}. * * @param event the event read from the underlying event reader. - * @param next {@code true} for a {@code next} operation, or {@code false} for a {@code peek} operation. * @return the converted event (may be the same instance). */ @SuppressWarnings("unchecked") // TODO: remove on JDK9 - private XMLEvent convert(XMLEvent event, final boolean next) { + private XMLEvent convert(XMLEvent event) { switch (event.getEventType()) { case ATTRIBUTE: { event = convert((Attribute) event); @@ -319,9 +368,7 @@ final class FilteredReader extends Filte } else { renamedAttributes.clear(); } - if (next) { - outerElements.add(e.getName()); - } + outerElements.add(name); break; } case END_ELEMENT: { @@ -337,12 +384,10 @@ final class FilteredReader extends Filte * Close the last start element with a matching name. It should be the last element * on the list in a well-formed XML, but we loop in the list anyway as a safety. */ - if (next) { - for (int i = outerElements.size(); --i >= 0;) { - if (name.equals(outerElements.get(i))) { - outerElements.remove(i); - break; - } + for (int i = outerElements.size(); --i >= 0;) { + if (name.equals(outerElements.get(i))) { + outerElements.remove(i); + break; } } break;