package votorola.a.position; // Copyright 2010-2013, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. import java.io.*; import java.net.*; import javax.ws.rs.core.UriBuilder; import javax.xml.stream.*; import votorola.g.*; import votorola.g.hold.*; import votorola.g.lang.*; /** An implementation of a page revision. */ @SuppressWarnings("overrides")/* overrides equals, but not hashCode*/ public @ThreadSafe class PageRevision1 implements PageRevision { /** Attempts to construct a PageRevision1 from the response to a page query. * * @param _xml a reader for the response to a page query that covers properties * 'info' or (if !_toLatest) 'info|revisions' in which at least one 'page' * element might remain to be read. * @param _toLatest true to read the revision from info 'lastrevid', or false to * read it from the 'revisions' that are included in the query. * * @return the constructed page revision, or null if no 'page' element remains * to be read. * * @throws MediaWiki.NoSuchItem if a requested page or revision does not exist. */ public static PageRevision readPageRevision( final URI wikiScriptURI, XMLStreamReader _xml, boolean _toLatest ) throws IOException, XMLStreamException { return readPageRevision( wikiScriptURI, _xml, _toLatest, wikiScriptURI.toASCIIString() + "/index.php", /*maybeUgly*/true ); } /** @param maybeUgly whether the wiki location might be the standard access location * ending in "index.php" for example, or is definitely a pretty alias per * $wgUsePathInfo. * * @throws MediaWiki.NoSuchItem if a requested page or revision does not exist. */ private static PageRevision readPageRevision( final URI wikiScriptURI, final XMLStreamReader xml, final boolean toLatest, final String wikiLocation, final boolean maybeUgly ) throws IOException, XMLStreamException { while( xml.hasNext() ) { xml.next(); if( !xml.isStartElement() ) continue; if( "page".equals( xml.getLocalName() )) { MediaWiki.testPage_missing( xml ); /* when querying by 'titles'; else if querying by 'revids' see 'badrevids' below */ final int pageID = Integer.parseInt( xml.getAttributeValue( /*ns*/null, "pageid" )); final String pageName = xml.getAttributeValue( /*ns*/null, "title" ); final int revLatest = Integer.parseInt( xml.getAttributeValue( /*ns*/null, "lastrevid" )); final int rev; rev: if( toLatest ) rev = revLatest; else { while( xml.hasNext() ) { xml.next(); if( xml.isEndElement() && "page".equals( xml.getLocalName() )) break; if( xml.isStartElement() && "rev".equals( xml.getLocalName() )) { rev = Integer.parseInt( xml.getAttributeValue( /*ns*/null, "revid" )); break rev; } } throw new MediaWiki.MalformedResponse( "missing 'rev' element" ); } return new PageRevision1( wikiScriptURI, pageID, pageName, rev, revLatest, wikiLocation, maybeUgly ); } MediaWiki.test_badrevids( xml ); /* when querying by 'revids'; else if querying by 'titles' see testPage_missing above */ MediaWiki.test_error( xml ); } return null; } /** Constructs a PageRevision1. * * @see #wikiScriptURI() * @see #pageID() * @param _pageName it will be normalized. * @see #rev() * @see #revLatest() * @param maybeUgly whether the wiki location might be the standard access * location ending in "index.php" for example, or is definitely a pretty alias * per $wgUsePathInfo. */ protected PageRevision1( URI _wikiScriptURI, int _pageID, String _pageName, int _rev, int _revLatest, final String wikiLocation, final boolean maybeUgly ) { wikiScriptURI = _wikiScriptURI; pageID = _pageID; pageName = MediaWiki.demiDecodedPageName( _pageName ); rev = _rev; revLatest = _revLatest; if( rev < 0 ) throw new IllegalArgumentException(); // test only because -1 used in DiffKey pageURI = MediaWiki.encodePageSpecifier( UriBuilder.fromUri(wikiLocation), maybeUgly, _pageName ).build(); try{ revURI = new URI( wikiScriptURI.toASCIIString() + "/index.php?oldid=" + rev ); } catch( URISyntaxException x ) { throw new RuntimeException( x ); } } /** Constructs a PageRevision1 as a copy of another instance of a page revision. */ protected PageRevision1( final PageRevision rP ) { pageID = rP.pageID(); pageName = rP.pageName(); pageURI = rP.pageURI(); rev = rP.rev(); revLatest = rP.revLatest(); revURI = rP.revURI(); wikiScriptURI = rP.wikiScriptURI(); } // - O b j e c t ------------------------------------------------------------------ /** Returns true iff o is a PageRevision having the same (equals) wiki script location * and revision identifier. * * @see #rev() * @see #wikiScriptURI() */ public final @Override boolean equals( Object o ) { if( !( o instanceof PageRevision )) return false; final PageRevision other = (PageRevision)o; return rev == other.rev() && wikiScriptURI.equals( other.wikiScriptURI() ); } /** Returns "r.{@linkplain #rev() rev}". */ public @Override String toString() { return "r." + rev(); } // - P a g e - R e v i s i o n -------------------------------------------------------- public boolean isLatestRevision() { return rev == revLatest; } public final int pageID() { return pageID; } private final int pageID; public final String pageName() { return pageName; } private final String pageName; public final URI pageURI() { return pageURI; } private final URI pageURI; public final int rev() { return rev; } private final int rev; public final int revLatest() { return revLatest; } private final int revLatest; public final URI revURI() { return revURI; } private final URI revURI; public final URI wikiScriptURI() { return wikiScriptURI; } private final URI wikiScriptURI; }