public SVNProperties asMap() throws SVNException {
   SVNProperties result = new SVNProperties();
   if (isEmpty()) {
     return result;
   }
   ByteArrayOutputStream nameOS = new ByteArrayOutputStream();
   InputStream is = SVNFileUtil.openFileForReading(getFile(), SVNLogType.WC);
   try {
     while (readProperty('K', is, nameOS)) {
       String name = new String(nameOS.toByteArray(), "UTF-8");
       nameOS.reset();
       readProperty('V', is, nameOS);
       byte[] value = nameOS.toByteArray();
       result.put(name, value);
       nameOS.reset();
     }
   } catch (IOException e) {
     SVNErrorMessage err =
         SVNErrorMessage.create(
             SVNErrorCode.IO_ERROR,
             "Cannot read properties file ''{0}'': {1}",
             new Object[] {getFile(), e.getLocalizedMessage()});
     SVNErrorManager.error(err, e, SVNLogType.WC);
   } finally {
     SVNFileUtil.closeFile(is);
   }
   return result;
 }
 public static void appendPropertyDeleted(String name, OutputStream target) throws SVNException {
   if (name == null) {
     return;
   }
   try {
     writeProperty(target, 'D', name.getBytes("UTF-8"));
   } catch (IOException ioe) {
     SVNErrorMessage err =
         SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
     SVNErrorManager.error(err, ioe, SVNLogType.WC);
   }
 }
  public static void appendProperty(String name, SVNPropertyValue value, OutputStream target)
      throws SVNException {
    if (name == null || value == null) {
      return;
    }

    byte[] bytes = SVNPropertyValue.getPropertyAsBytes(value);

    try {
      writeProperty(target, 'K', name.getBytes("UTF-8"));
      writeProperty(target, 'V', bytes);
    } catch (IOException ioe) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
      SVNErrorManager.error(err, ioe, SVNLogType.WC);
    }
  }
  /** @noinspection ResultOfMethodCallIgnored */
  private static boolean copyProperties(
      InputStream is, OutputStream os, String name, InputStream value, int length)
      throws SVNException {
    // read names, till name is met, then insert value or skip this
    // property.
    int propCount = 0;
    try {
      if (is != null) {
        int l = 0;
        while ((l = readLength(is, 'K')) > 0) {
          byte[] nameBytes = new byte[l];

          SVNFileUtil.readIntoBuffer(is, nameBytes, 0, nameBytes.length);
          is.read();
          if (name.equals(new String(nameBytes, "UTF-8"))) {
            // skip property, will be appended.
            readProperty('V', is, null);
            continue;
          }
          // save name
          writeProperty(os, 'K', nameBytes);
          l = readLength(is, 'V');
          writeProperty(os, 'V', is, l);
          is.read();
          propCount++;
        }
      }
      if (value != null && length >= 0) {
        byte[] nameBytes = name.getBytes("UTF-8");
        writeProperty(os, 'K', nameBytes);
        writeProperty(os, 'V', value, length);
        propCount++;
      }
      if (propCount > 0) {
        os.write(new byte[] {'E', 'N', 'D', '\n'});
      }
    } catch (IOException e) {
      SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e.getLocalizedMessage());
      SVNErrorManager.error(err, e, SVNLogType.WC);
    }
    return propCount > 0;
  }
 public Collection properties(Collection target) throws SVNException {
   target = target == null ? new TreeSet() : target;
   if (isEmpty()) {
     return target;
   }
   ByteArrayOutputStream nameOS = new ByteArrayOutputStream();
   InputStream is = SVNFileUtil.openFileForReading(getFile(), SVNLogType.WC);
   try {
     while (readProperty('K', is, nameOS)) {
       target.add(new String(nameOS.toByteArray(), "UTF-8"));
       nameOS.reset();
       readProperty('V', is, null);
     }
   } catch (IOException e) {
     SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e.getLocalizedMessage());
     SVNErrorManager.error(err, e, SVNLogType.WC);
   } finally {
     SVNFileUtil.closeFile(is);
   }
   return target;
 }
 public static void setProperties(
     SVNProperties namesToValues, OutputStream target, String terminator) throws SVNException {
   try {
     Object[] keys = namesToValues.nameSet().toArray();
     Arrays.sort(keys);
     for (int i = 0; i < keys.length; i++) {
       String propertyName = (String) keys[i];
       writeProperty(target, 'K', propertyName.getBytes("UTF-8"));
       writeProperty(
           target,
           'V',
           SVNPropertyValue.getPropertyAsBytes(namesToValues.getSVNPropertyValue(propertyName)));
     }
     if (terminator != null) {
       target.write(terminator.getBytes("UTF-8"));
       target.write('\n');
     }
   } catch (IOException ioe) {
     SVNErrorMessage err =
         SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
     SVNErrorManager.error(err, ioe, SVNLogType.WC);
   }
 }
 public OutputStream getPropertyValue(String name, OutputStream os) throws SVNException {
   if (isEmpty()) {
     return null;
   }
   ByteArrayOutputStream nameOS = new ByteArrayOutputStream();
   InputStream is = SVNFileUtil.openFileForReading(getFile(), SVNLogType.WC);
   try {
     while (readProperty('K', is, nameOS)) {
       String currentName = new String(nameOS.toByteArray(), "UTF-8");
       nameOS.reset();
       if (currentName.equals(name)) {
         readProperty('V', is, os);
         return os;
       }
       readProperty('V', is, null);
     }
   } catch (IOException e) {
     SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e.getLocalizedMessage());
     SVNErrorManager.error(err, e, SVNLogType.WC);
   } finally {
     SVNFileUtil.closeFile(is);
   }
   return null;
 }
  @Override
  protected SvnStatus run(SVNWCContext context) throws SVNException {
    File directoryPath;
    String targetName;

    SVNNodeKind kind = context.readKind(getFirstTarget(), false);
    SVNDepth depth = getOperation().getDepth();
    if (kind == SVNNodeKind.DIR) {
      directoryPath = getFirstTarget();
      targetName = "";
    } else {
      directoryPath = SVNFileUtil.getParentFile(getFirstTarget());
      targetName = SVNFileUtil.getFileName(getFirstTarget());
      if (kind == SVNNodeKind.FILE) {
        if (depth == SVNDepth.EMPTY) {
          depth = SVNDepth.FILES;
        }
      } else {
        boolean notAWc = false;
        try {
          kind = context.readKind(directoryPath, false);
          notAWc = kind != SVNNodeKind.DIR;
        } catch (SVNException e) {
          notAWc = true;
        }
        if (notAWc) {
          SVNErrorMessage err =
              SVNErrorMessage.create(
                  SVNErrorCode.WC_PATH_NOT_FOUND,
                  "The node ''{0}'' was not found",
                  getFirstTarget());
          SVNErrorManager.error(err, SVNLogType.WC);
        }
      }
    }

    String[] globalIgnores = context.getOptions().getIgnorePatterns();

    if (getOperation().isRemote()) {
      SVNURL url = context.getUrlFromPath(directoryPath);
      if (url == null) {
        SVNErrorMessage error =
            SVNErrorMessage.create(
                SVNErrorCode.ENTRY_MISSING_URL, "Entry ''{0}'' has no URL", directoryPath);
        SVNErrorManager.error(error, SVNLogType.WC);
      }
      SVNRepository repository = getRepositoryAccess().createRepository(url, null, true);
      long rev;
      if (getOperation().getRevision() == SVNRevision.HEAD) {
        rev = -1;
      } else {
        rev =
            context.getRevisionNumber(
                getOperation().getRevision(), null, repository, getFirstTarget());
      }
      kind = repository.checkPath("", rev);
      checkCancelled();
      SVNStatusEditor17 editor = null;
      SVNReporter17 reporter = null;
      if (kind == SVNNodeKind.NONE) {
        boolean added = context.isNodeAdded(directoryPath);
        if (added) {
          boolean replaced = context.isNodeReplaced(directoryPath);
          if (replaced) {
            added = false;
          }
        }
        setTargetDeletedInRepository(!added);
        editor =
            new SVNStatusEditor17(
                getFirstTarget(),
                context,
                getOperation().getOptions(),
                getOperation().isReportIgnored(),
                getOperation().isReportAll(),
                depth,
                this);
        editor.setFileListHook(getOperation().getFileListHook());
        checkCancelled();
        editor.closeEdit();
      } else {
        editor =
            new SVNRemoteStatusEditor17(
                directoryPath,
                targetName,
                context,
                getOperation().getOptions(),
                getOperation().isReportIgnored(),
                getOperation().isReportAll(),
                depth,
                this);
        editor.setFileListHook(getOperation().getFileListHook());

        SVNRepository locksRepos = getRepositoryAccess().createRepository(url, null, false);
        checkCancelled();
        boolean serverSupportsDepth = repository.hasCapability(SVNCapability.DEPTH);
        reporter =
            new SVNReporter17(
                getFirstTarget(),
                context,
                false,
                !serverSupportsDepth,
                depth,
                false,
                true,
                true,
                false,
                null);
        SVNStatusReporter17 statusReporter = new SVNStatusReporter17(locksRepos, reporter, editor);
        String target = "".equals(targetName) ? null : targetName;
        SVNDepth statusDepth = getOperation().isDepthAsSticky() ? depth : SVNDepth.UNKNOWN;
        repository.status(
            rev,
            target,
            statusDepth,
            statusReporter,
            SVNCancellableEditor.newInstance((ISVNEditor) editor, this, null));
      }
      getOperation().setRemoteRevision(editor.getTargetRevision());

      long reportedFiles = reporter != null ? reporter.getReportedFilesCount() : 0;
      long totalFiles = reporter != null ? reporter.getTotalFilesCount() : 0;
      SVNEvent event =
          SVNEventFactory.createSVNEvent(
              getFirstTarget(),
              SVNNodeKind.NONE,
              null,
              editor.getTargetRevision(),
              SVNEventAction.STATUS_COMPLETED,
              null,
              null,
              null,
              reportedFiles,
              totalFiles);

      handleEvent(event, ISVNEventHandler.UNKNOWN);
    } else {
      SVNStatusEditor17 editor =
          new SVNStatusEditor17(
              directoryPath,
              context,
              context.getOptions(),
              getOperation().isReportIgnored(),
              getOperation().isReportAll(),
              depth,
              this);
      editor.setFileListHook(getOperation().getFileListHook());
      try {
        editor.walkStatus(
            getFirstTarget(),
            depth,
            getOperation().isReportAll(),
            getOperation().isReportIgnored(),
            false,
            globalIgnores != null ? Arrays.asList(globalIgnores) : null);
      } catch (SVNException e) {
        if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_MISSING) {
          SVNErrorMessage err =
              SVNErrorMessage.create(
                  SVNErrorCode.WC_NOT_WORKING_COPY,
                  "''{0}'' is not a working copy",
                  getFirstTarget());
          SVNErrorManager.error(err, SVNLogType.WC);
        }
        throw e;
      }
    }

    if (depth.isRecursive() && getOperation().isReportExternals()) {
      Map<File, File> externals = context.getDb().getExternalsDefinedBelow(getFirstTarget());
      doExternalStatus(externals);
    }

    return getOperation().first();
  }
  public boolean compareTo(SVNWCProperties properties, ISVNPropertyComparator comparator)
      throws SVNException {
    boolean equals = true;
    Collection props1 = properties(null);
    Collection props2 = properties.properties(null);

    // missed in props2.
    Collection tmp = new TreeSet(props1);
    tmp.removeAll(props2);
    for (Iterator props = tmp.iterator(); props.hasNext(); ) {
      String missing = (String) props.next();
      comparator.propertyDeleted(missing);
      equals = false;
    }

    // added in props2.
    tmp = new TreeSet(props2);
    tmp.removeAll(props1);

    File tmpFile = null;
    File tmpFile1 = null;
    File tmpFile2 = null;
    OutputStream os = null;
    InputStream is = null;
    InputStream is1 = null;
    InputStream is2 = null;

    for (Iterator props = tmp.iterator(); props.hasNext(); ) {
      String added = (String) props.next();
      try {
        tmpFile =
            SVNFileUtil.createUniqueFile(
                getFile().getParentFile(), getFile().getName(), ".tmp", true);

        os = SVNFileUtil.openFileForWriting(tmpFile);
        properties.getPropertyValue(added, os);
        SVNFileUtil.closeFile(os);

        is = SVNFileUtil.openFileForReading(tmpFile, SVNLogType.WC);
        comparator.propertyAdded(added, is, (int) tmpFile.length());
        equals = false;
        SVNFileUtil.closeFile(is);
      } finally {
        if (tmpFile != null) {
          tmpFile.delete();
        }
        SVNFileUtil.closeFile(os);
        SVNFileUtil.closeFile(is);
        tmpFile = null;
        is = null;
        os = null;
      }
    }

    // changed in props2
    props2.retainAll(props1);
    for (Iterator props = props2.iterator(); props.hasNext(); ) {
      String changed = (String) props.next();

      try {
        tmpFile1 =
            SVNFileUtil.createUniqueFile(
                getFile().getParentFile(), getFile().getName(), ".tmp1", true);
        tmpFile2 =
            SVNFileUtil.createUniqueFile(
                getFile().getParentFile(), getFile().getName(), ".tmp2", true);

        os = SVNFileUtil.openFileForWriting(tmpFile1);
        getPropertyValue(changed, os);
        os.close();
        os = SVNFileUtil.openFileForWriting(tmpFile2);
        properties.getPropertyValue(changed, os);
        os.close();
        if (tmpFile2.length() != tmpFile1.length()) {
          is = SVNFileUtil.openFileForReading(tmpFile2, SVNLogType.WC);
          comparator.propertyChanged(changed, is, (int) tmpFile2.length());
          equals = false;
          SVNFileUtil.closeFile(is);
        } else {
          is1 = SVNFileUtil.openFileForReading(tmpFile1, SVNLogType.WC);
          is2 = SVNFileUtil.openFileForReading(tmpFile2, SVNLogType.WC);
          boolean differs = false;
          for (int i = 0; i < tmpFile1.length(); i++) {
            if (is1.read() != is2.read()) {
              differs = true;
              break;
            }
          }
          SVNFileUtil.closeFile(is1);
          SVNFileUtil.closeFile(is2);
          if (differs) {
            is2 = SVNFileUtil.openFileForReading(tmpFile2, SVNLogType.WC);
            comparator.propertyChanged(changed, is2, (int) tmpFile2.length());
            equals = false;
            SVNFileUtil.closeFile(is2);
          }
        }
      } catch (IOException e) {
        SVNErrorMessage err =
            SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e.getLocalizedMessage());
        SVNErrorManager.error(err, e, SVNLogType.WC);
      } finally {
        if (tmpFile2 != null) {
          tmpFile2.delete();
        }
        if (tmpFile1 != null) {
          tmpFile1.delete();
        }
        SVNFileUtil.closeFile(os);
        SVNFileUtil.closeFile(is);
        SVNFileUtil.closeFile(is1);
        SVNFileUtil.closeFile(is2);
        os = null;
        tmpFile1 = tmpFile2 = null;
        is = is1 = is2 = null;
      }
    }
    return equals;
  }