| /* |
| * Copyright 2000-2012 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.jetbrains.idea.svn.commandLine; |
| |
| import com.intellij.openapi.util.Getter; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.util.Consumer; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.tmatesoft.svn.core.SVNDepth; |
| import org.tmatesoft.svn.core.SVNException; |
| import org.tmatesoft.svn.core.SVNNodeKind; |
| import org.tmatesoft.svn.core.SVNURL; |
| import org.tmatesoft.svn.core.internal.util.SVNDate; |
| import org.tmatesoft.svn.core.wc.SVNInfo; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| import java.io.File; |
| import java.util.*; |
| |
| /** |
| * Created with IntelliJ IDEA. |
| * User: Irina.Chernushina |
| * Date: 1/27/12 |
| * Time: 1:00 PM |
| */ |
| public class SvnInfoHandler extends DefaultHandler { |
| @Nullable private final File myBase; |
| private final Consumer<SVNInfo> myInfoConsumer; |
| private Map<File, SVNInfo> myResultsMap; |
| private SvnInfoStructure myPending; |
| private final Map<String, Getter<ElementHandlerBase>> myElementsMap; |
| private final List<ElementHandlerBase> myParseStack; |
| private final StringBuilder mySb; |
| |
| public SvnInfoHandler(@Nullable File base, final Consumer<SVNInfo> infoConsumer) { |
| myBase = base; |
| myInfoConsumer = infoConsumer; |
| myPending = createPending(); |
| myElementsMap = new HashMap<String, Getter<ElementHandlerBase>>(); |
| fillElements(); |
| myParseStack = new ArrayList<ElementHandlerBase>(); |
| myParseStack.add(new Fake()); |
| myResultsMap = new HashMap<File, SVNInfo>(); |
| mySb = new StringBuilder(); |
| } |
| |
| private void switchPending() throws SAXException { |
| final SVNInfo info; |
| try { |
| info = myPending.convert(); |
| } |
| catch (SVNException e) { |
| throw new SAXException(e); |
| } |
| if (myInfoConsumer != null) { |
| myInfoConsumer.consume(info); |
| } |
| myResultsMap.put(info.getFile(), info); |
| myPending = createPending(); |
| } |
| |
| private SvnInfoStructure createPending() { |
| SvnInfoStructure pending = new SvnInfoStructure(); |
| pending.myDepth = SVNDepth.INFINITY; |
| |
| return pending; |
| } |
| |
| @Override |
| public void endDocument() throws SAXException { |
| assertSAX(! myParseStack.isEmpty()); |
| for (int i = myParseStack.size() - 1; i >= 0; -- i) { |
| ElementHandlerBase current = myParseStack.get(i); |
| if (current instanceof Entry) { |
| switchPending(); |
| break; |
| } |
| } |
| myParseStack.clear(); |
| } |
| |
| @Override |
| public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { |
| assertSAX(! myParseStack.isEmpty()); |
| ElementHandlerBase current = myParseStack.get(myParseStack.size() - 1); |
| |
| while (true) { |
| final boolean createNewChild = current.startElement(uri, localName, qName, attributes); |
| if (createNewChild) { |
| assertSAX(myElementsMap.containsKey(qName)); |
| final ElementHandlerBase newChild = myElementsMap.get(qName).get(); |
| newChild.setParent(current); |
| newChild.updateInfo(attributes, myPending); |
| myParseStack.add(newChild); |
| return; |
| } else { |
| // go up |
| if (current instanceof Entry) { |
| switchPending(); |
| } |
| myParseStack.remove(myParseStack.size() - 1); |
| assertSAX(! myParseStack.isEmpty()); |
| current = myParseStack.get(myParseStack.size() - 1); |
| } |
| } |
| } |
| |
| @Override |
| public void endElement(String uri, String localName, String qName) throws SAXException { |
| ElementHandlerBase current = myParseStack.get(myParseStack.size() - 1); |
| String value = mySb.toString().trim(); |
| |
| if (!StringUtil.isEmpty(value)) { |
| current.characters(value, myPending); |
| } |
| |
| mySb.setLength(0); |
| } |
| |
| @Override |
| public void characters(char[] ch, int start, int length) throws SAXException { |
| assertSAX(! myParseStack.isEmpty()); |
| mySb.append(ch, start, length); |
| } |
| |
| public Map<String, Getter<ElementHandlerBase>> getElementsMap() { |
| return myElementsMap; |
| } |
| |
| private void fillElements() { |
| myElementsMap.put("copy-from-url", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new CopyFromUrl(); |
| } |
| }); |
| myElementsMap.put("copy-from-rev", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new CopyFromRev(); |
| } |
| }); |
| myElementsMap.put("changelist", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new ChangeList(); |
| } |
| }); |
| myElementsMap.put("author", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Author(); |
| } |
| }); |
| myElementsMap.put("checksum", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Checksum(); |
| } |
| }); |
| myElementsMap.put("commit", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Commit(); |
| } |
| }); |
| myElementsMap.put("conflict", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Conflict(); |
| } |
| }); |
| myElementsMap.put("cur-base-file", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new CurBase(); |
| } |
| }); |
| myElementsMap.put("date", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Date(); |
| } |
| }); |
| myElementsMap.put("depth", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Depth(); |
| } |
| }); |
| myElementsMap.put("entry", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Entry(myBase); |
| } |
| }); |
| myElementsMap.put("info", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Info(); |
| } |
| }); |
| myElementsMap.put("prev-base-file", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new PrevBase(); |
| } |
| }); |
| myElementsMap.put("prev-wc-file", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new PrevWc(); |
| } |
| }); |
| myElementsMap.put("prop-file", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new PropFile(); |
| } |
| }); |
| myElementsMap.put("repository", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Repository(); |
| } |
| }); |
| myElementsMap.put("root", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Root(); |
| } |
| }); |
| myElementsMap.put("schedule", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Schedule(); |
| } |
| }); |
| myElementsMap.put("text-updated", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new TextUpdated(); |
| } |
| }); |
| myElementsMap.put("tree-conflict", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new TreeConflict(); |
| } |
| }); |
| myElementsMap.put("url", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Url(); |
| } |
| }); |
| myElementsMap.put("relative-url", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new RelativeUrl(); |
| } |
| }); |
| myElementsMap.put("lock", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Lock(); |
| } |
| }); |
| myElementsMap.put("token", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new LockToken(); |
| } |
| }); |
| myElementsMap.put("owner", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new LockOwner(); |
| } |
| }); |
| myElementsMap.put("comment", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new LockComment(); |
| } |
| }); |
| myElementsMap.put("created", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new LockCreated(); |
| } |
| }); |
| myElementsMap.put("uuid", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Uuid(); |
| } |
| }); |
| myElementsMap.put("version", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new Version(); |
| } |
| }); |
| myElementsMap.put("wc-info", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new WcInfo(); |
| } |
| }); |
| myElementsMap.put("moved-to", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new MovedPath(); |
| } |
| }); |
| myElementsMap.put("moved-from", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new MovedPath(); |
| } |
| }); |
| myElementsMap.put("wcroot-abspath", new Getter<ElementHandlerBase>() { |
| @Override |
| public ElementHandlerBase get() { |
| return new WcRoot(); |
| } |
| }); |
| } |
| |
| public Map<File, SVNInfo> getResultsMap() { |
| return myResultsMap; |
| } |
| |
| private static void assertSAX(final boolean shouldBeTrue) throws SAXException { |
| if (! shouldBeTrue) { |
| throw new SAXException("can not parse output"); |
| } |
| } |
| |
| private static class Version extends ElementHandlerBase { |
| private Version() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| // TODO: Currently information for conflict (not tree-conflict) available in svn 1.8 is not used |
| // TODO: And it also not suite well for SVNKit api |
| if (getParent() instanceof Conflict) { |
| return; |
| } |
| |
| final String side = attributes.getValue("side"); |
| if ("source-left".equals(side)) { |
| final SvnInfoStructure.ConflictVersion conflictVersion = new SvnInfoStructure.ConflictVersion(); |
| structure.myTreeConflict.mySourceLeft = conflictVersion; |
| setConflictFields(attributes, conflictVersion); |
| } else if ("source-right".equals(side)) { |
| final SvnInfoStructure.ConflictVersion conflictVersion = new SvnInfoStructure.ConflictVersion(); |
| structure.myTreeConflict.mySourceRight = conflictVersion; |
| setConflictFields(attributes, conflictVersion); |
| } |
| } |
| |
| private void setConflictFields(Attributes attributes, SvnInfoStructure.ConflictVersion conflictVersion) { |
| conflictVersion.myKind = attributes.getValue("kind"); |
| conflictVersion.myPathInRepo = attributes.getValue("path-in-repos"); |
| conflictVersion.myRepoUrl = attributes.getValue("repos-url"); |
| conflictVersion.myRevision = attributes.getValue("revision"); |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| } |
| } |
| |
| private static class TreeConflict extends ElementHandlerBase { |
| private TreeConflict() { |
| super(new String[]{}, new String[]{"version"}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| final SvnInfoStructure.TreeConflictDescription d = new SvnInfoStructure.TreeConflictDescription(); |
| structure.myTreeConflict = d; |
| final String operation = attributes.getValue("operation"); |
| if (! StringUtil.isEmptyOrSpaces(operation)) { |
| d.myOperation = operation; |
| } |
| final String kind = attributes.getValue("kind"); |
| if (! StringUtil.isEmptyOrSpaces(kind)) { |
| d.myKind = kind; |
| } |
| final String reason = attributes.getValue("reason"); |
| if (! StringUtil.isEmptyOrSpaces(reason)) { |
| d.myReason = reason; |
| } |
| final String victim = attributes.getValue("victim"); |
| if (! StringUtil.isEmptyOrSpaces(victim)) { |
| d.myVictim = victim; |
| } |
| final String action = attributes.getValue("action"); |
| if (! StringUtil.isEmptyOrSpaces(action)) { |
| d.myAction = action; |
| } |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| } |
| } |
| |
| private static class PropFile extends ElementHandlerBase { |
| private PropFile() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| // todo check whether base should be added |
| structure.myPropRejectFile = s; |
| } |
| } |
| |
| private static class CurBase extends ElementHandlerBase { |
| private CurBase() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myConflictNew = new File(s).getName(); |
| } |
| } |
| |
| private static class PrevWc extends ElementHandlerBase { |
| private PrevWc() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myConflictWorking = new File(s).getName(); |
| } |
| } |
| |
| private static class PrevBase extends ElementHandlerBase { |
| private PrevBase() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myConflictOld = new File(s).getName(); |
| } |
| } |
| |
| private static class Conflict extends ElementHandlerBase { |
| private Conflict() { |
| super(new String[]{"prev-base-file","prev-wc-file","cur-base-file","prop-file"}, new String[]{"version"}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| } |
| } |
| |
| private static class Date extends ElementHandlerBase { |
| private Date() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| final SVNDate date = SVNDate.parseDate(s); |
| structure.myCommittedDate = date; |
| } |
| } |
| |
| private static class Author extends ElementHandlerBase { |
| private Author() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myAuthor = s; |
| } |
| } |
| |
| private static class Commit extends ElementHandlerBase { |
| private Commit() { |
| super(new String[]{"author","date"}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| final String revision = attributes.getValue("revision"); |
| try { |
| final long number = Long.parseLong(revision); |
| structure.myCommittedRevision = number; |
| } catch (NumberFormatException e) { |
| throw new SAXException(e); |
| } |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| } |
| } |
| |
| private static class Checksum extends ElementHandlerBase { |
| private Checksum() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myChecksum = s; |
| } |
| } |
| |
| /** |
| * "moved-from" and "moved-to" elements are represented by this class. |
| */ |
| private static class MovedPath extends ElementHandlerBase { |
| |
| private MovedPath() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| // TODO: is there some field to initialize from this value? |
| } |
| } |
| |
| private static class TextUpdated extends ElementHandlerBase { |
| private TextUpdated() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| final SVNDate date = SVNDate.parseDate(s); |
| structure.myTextTime = date; |
| } |
| } |
| |
| private static class Depth extends ElementHandlerBase { |
| private Depth() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myDepth = SVNDepth.fromString(s); |
| } |
| } |
| |
| private static class Schedule extends ElementHandlerBase { |
| private Schedule() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.mySchedule = s; |
| } |
| } |
| |
| private static class WcRoot extends ElementHandlerBase { |
| private WcRoot() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| // there is no such thing??? |
| } |
| } |
| |
| private static class ChangeList extends ElementHandlerBase { |
| private ChangeList() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myChangelistName = s; |
| } |
| } |
| |
| private static class CopyFromUrl extends ElementHandlerBase { |
| private CopyFromUrl() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| try { |
| structure.myCopyFromURL = SVNURL.parseURIEncoded(s); |
| } |
| catch (SVNException e) { |
| throw new SAXException(e); |
| } |
| } |
| } |
| |
| private static class CopyFromRev extends ElementHandlerBase { |
| private CopyFromRev() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| try { |
| final long number = Long.parseLong(s); |
| structure.myCopyFromRevision = number; |
| } catch (NumberFormatException e) { |
| throw new SAXException(e); |
| } |
| } |
| } |
| |
| private static class WcInfo extends ElementHandlerBase { |
| private WcInfo() { |
| super(new String[]{"wcroot-abspath", "schedule", "depth", "text-updated", "checksum", "changelist", "copy-from-url", |
| "copy-from-rev", "moved-to", "moved-from"}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| } |
| } |
| |
| private static class Uuid extends ElementHandlerBase { |
| private Uuid() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myUuid = s; |
| } |
| } |
| |
| private static class Root extends ElementHandlerBase { |
| private Root() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| try { |
| structure.myRootURL = SVNURL.parseURIEncoded(s); |
| } |
| catch (SVNException e) { |
| throw new SAXException(e); |
| } |
| } |
| } |
| |
| private static class Repository extends ElementHandlerBase { |
| private Repository() { |
| super(new String[]{"root", "uuid"}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| } |
| } |
| |
| private static class Url extends ElementHandlerBase { |
| private Url() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| try { |
| structure.myUrl = SVNURL.parseURIEncoded(s); |
| } |
| catch (SVNException e) { |
| throw new SAXException(e); |
| } |
| } |
| } |
| |
| private static class RelativeUrl extends Url{ |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.relativeUrl = s; |
| } |
| } |
| |
| private static class Lock extends ElementHandlerBase { |
| private Lock() { |
| super(new String[]{"token", "owner", "comment", "created"}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| structure.myLockWrapper = new SVNLockWrapper(); |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| } |
| } |
| |
| private static class LockToken extends ElementHandlerBase { |
| private LockToken() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myLockWrapper.setID(s); |
| } |
| } |
| |
| private static class LockOwner extends ElementHandlerBase { |
| private LockOwner() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myLockWrapper.setOwner(s); |
| } |
| } |
| |
| private static class LockComment extends ElementHandlerBase { |
| private LockComment() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myLockWrapper.setComment(s); |
| } |
| } |
| |
| private static class LockCreated extends ElementHandlerBase { |
| private LockCreated() { |
| super(new String[]{}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) throws SAXException { |
| structure.myLockWrapper.setCreationDate(SVNDate.parseDate(s)); |
| } |
| } |
| |
| private static class Entry extends ElementHandlerBase { |
| @Nullable private final File myBase; |
| |
| private Entry(@Nullable final File base) { |
| super(new String[]{"url", "relative-url", "lock", "repository","wc-info","commit","conflict","tree-conflict"}, new String[]{}); |
| myBase = base; |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException { |
| final String kind = attributes.getValue("kind"); |
| assertSAX(! StringUtil.isEmptyOrSpaces(kind)); |
| structure.myKind = SVNNodeKind.parseKind(kind); |
| |
| if (myBase != null) { |
| final String path = attributes.getValue("path"); |
| assertSAX(!StringUtil.isEmptyOrSpaces(path)); |
| structure.myFile = new File(myBase, path); |
| } |
| |
| final String revision = attributes.getValue("revision"); |
| assertSAX(! StringUtil.isEmptyOrSpaces(revision)); |
| try { |
| final long number = Long.parseLong(revision); |
| structure.myRevision = number; |
| } catch (NumberFormatException e) { |
| structure.myRevision = -1; |
| //throw new SAXException(e); |
| } |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) { |
| } |
| } |
| |
| private static class Info extends ElementHandlerBase { |
| private Info() { |
| super(new String[]{}, new String[]{"entry"}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) { |
| } |
| } |
| |
| private static class Fake extends ElementHandlerBase { |
| private Fake() { |
| super(new String[]{"info"}, new String[]{}); |
| } |
| |
| @Override |
| protected void updateInfo(Attributes attributes, SvnInfoStructure structure) { |
| } |
| |
| @Override |
| public void characters(String s, SvnInfoStructure structure) { |
| } |
| } |
| |
| private abstract static class ElementHandlerBase { |
| private final Set<String> myAwaitedChildren; |
| private final Set<String> myAwaitedChildrenMultiple; |
| private ElementHandlerBase parent; |
| |
| ElementHandlerBase(String[] awaitedChildren, String[] awaitedChildrenMultiple) { |
| myAwaitedChildren = new HashSet<String>(Arrays.asList(awaitedChildren)); |
| myAwaitedChildrenMultiple = new HashSet<String>(Arrays.asList(awaitedChildrenMultiple)); |
| } |
| |
| @NotNull |
| public ElementHandlerBase getParent() { |
| return parent; |
| } |
| |
| public void setParent(@NotNull ElementHandlerBase parent) { |
| this.parent = parent; |
| } |
| |
| protected abstract void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException; |
| |
| public boolean startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { |
| if (myAwaitedChildrenMultiple.contains(qName)) { |
| return true; |
| } |
| return myAwaitedChildren.remove(qName); |
| } |
| |
| public abstract void characters(String s, SvnInfoStructure structure) throws SAXException; |
| } |
| } |