public void copyItem(ResourceStoreRequest from, ResourceStoreRequest to)
      throws UnsupportedStorageOperationException, ItemNotFoundException, IllegalOperationException,
          StorageException, AccessDeniedException {
    RequestRoute fromRoute = getRequestRouteForRequest(from);

    RequestRoute toRoute = getRequestRouteForRequest(to);

    if (fromRoute.isRepositoryHit() && toRoute.isRepositoryHit()) {
      // it hits a repository, mangle path and call it

      try {
        from.pushRequestPath(fromRoute.getRepositoryPath());
        to.pushRequestPath(toRoute.getRepositoryPath());

        if (fromRoute.getTargetedRepository() == toRoute.getTargetedRepository()) {
          fromRoute.getTargetedRepository().copyItem(from, to);
        } else {
          StorageItem item = fromRoute.getTargetedRepository().retrieveItem(from);

          if (item instanceof StorageFileItem) {
            try {
              toRoute
                  .getTargetedRepository()
                  .storeItem(
                      to,
                      ((StorageFileItem) item).getInputStream(),
                      item.getRepositoryItemAttributes().asMap());
            } catch (IOException e) {
              // XXX: this is nonsense, to box IOException into subclass of IOException!
              throw new LocalStorageException(e);
            }
          } else if (item instanceof StorageCollectionItem) {
            toRoute
                .getTargetedRepository()
                .createCollection(to, item.getRepositoryItemAttributes().asMap());
          } else {
            throw new IllegalRequestException(
                from,
                "Cannot copy item of class='"
                    + item.getClass().getName()
                    + "' over multiple repositories.");
          }
        }
      } finally {
        from.popRequestPath();
        to.popRequestPath();
      }
    } else {
      // this is "above" repositories
      if (!fromRoute.isRepositoryHit()) {
        throw new IllegalRequestException(
            from, "The path '" + from.getRequestPath() + "' does not points to any repository!");
      } else {
        throw new IllegalRequestException(
            to, "The path '" + to.getRequestPath() + "' does not points to any repository!");
      }
    }
  }
  protected void gatherArtifactNodeInfoIfAvailable(
      final String path, final DefaultMergedTreeNode mnode) {
    if (!CHECK_LOCAL_AVAILABILITY) {
      return;
    }

    final ResourceStoreRequest request = getResourceStoreRequest(path);
    // default it to not available
    mnode.setLocallyAvailable(false);
    try {
      final StorageItem item = getRepository().retrieveItem(request);
      if (item instanceof StorageFileItem) {
        mnode.setLocallyAvailable(true);
        mnode.setArtifactTimestamp(item.getModified());
        mnode.setArtifactMd5Checksum(
            item.getRepositoryItemAttributes().get(DigestCalculatingInspector.DIGEST_MD5_KEY));
        mnode.setArtifactSha1Checksum(
            item.getRepositoryItemAttributes().get(DigestCalculatingInspector.DIGEST_SHA1_KEY));
        mnode.setInitiatorUserId(
            item.getRepositoryItemAttributes().get(AccessManager.REQUEST_USER));
        mnode.setInitiatorIpAddress(
            item.getRepositoryItemAttributes().get(AccessManager.REQUEST_REMOTE_ADDRESS));
        mnode.setArtifactOriginUrl(item.getRemoteUrl());
        if (!StringUtils.isEmpty(mnode.getArtifactOriginUrl())) {
          mnode.setArtifactOriginReason("cached");
        } else {
          mnode.setArtifactOriginReason("deployed");
        }
      }
    } catch (ItemNotFoundException e) {
      // mute it, probably not available locally
    } catch (AccessDeniedException e) {
      // mute it, probably user does not have authz to access this part of repo
    } catch (IllegalOperationException e) {
      // like "repo is out of service", but why is then tree view accessed at all? In that case it's
      // a bug
      logger.warn(
          "Illegal operation tried against repository {}",
          RepositoryStringUtils.getHumanizedNameString(getRepository()),
          e);
    } catch (StorageException e) {
      // this is lethal, some "io related" problem. Is basically IOException and is a problem on
      // your instance or HW/net
      logger.warn(
          "IO related problem in repository {}",
          RepositoryStringUtils.getHumanizedNameString(getRepository()),
          e);
    }
  }
 private void putChecksumItem(
     Map<String, StorageItem> checksums,
     ResourceStoreRequest request,
     StorageItem artifact,
     String attrname,
     String suffix) {
   String hash = artifact.getRepositoryItemAttributes().get(attrname);
   if (hash != null) {
     String hashPath = artifact.getPath() + suffix;
     request.pushRequestPath(hashPath);
     try {
       checksums.put(hashPath, newHashItem(this, request, artifact, hash));
     } finally {
       request.popRequestPath();
     }
   }
 }