/**
   * Resolves all spaces represented by the given query uri
   *
   * @param queryUri Data Spaces URI to query for; must be URI without space part being fully
   *     defined, i.e. not pointing to any concrete data space; result spaces for that queries must
   *     be suitable for user path.
   * @param ownerActiveObjectId Id of active object requesting this files, that will become owner of
   *     returned {@link DataSpacesFileObject} instances. May be <code>null</code>, which
   *     corresponds to anonymous (unimportant) owner.
   * @return
   * @throws FileSystemException
   */
  public Map<DataSpacesURI, DataSpacesFileObject> resolveSpaces(
      final DataSpacesURI queryUri, final String ownerActiveObjectId) throws FileSystemException {

    final Map<DataSpacesURI, DataSpacesFileObject> result =
        new HashMap<DataSpacesURI, DataSpacesFileObject>();
    if (logger.isDebugEnabled())
      logger.debug("[VFSMountManager] Spaces access request: " + queryUri);

    final Set<SpaceInstanceInfo> spaces = directory.lookupMany(queryUri);
    if (spaces != null) {
      for (final SpaceInstanceInfo space : spaces) {
        final DataSpacesURI spaceUri = space.getMountingPoint();
        if (!spaceUri.isSuitableForUserPath()) {
          logger.error(
              "[VFSMountManager] Resolved space is not suitable for user path: " + spaceUri);
          throw new IllegalArgumentException(
              "Resolved space is not suitable for user path: " + spaceUri);
        }
        try {
          ensureVirtualSpaceIsMounted(spaceUri, space);
        } catch (SpaceNotFoundException e) {
          ProActiveLogger.logImpossibleException(logger, e);
          throw new RuntimeException(e);
        }
        result.put(spaceUri, doResolveFile(spaceUri, ownerActiveObjectId, null));
      }
    }
    return result;
  }
 private void assertIsSpaceUnregistered(SpaceInstanceInfo expected) {
   assertNull(stub.lookupOne(expected.getMountingPoint()));
 }
 private void assertIsSpaceRegistered(SpaceInstanceInfo expected) {
   SpaceInstanceInfo actual = stub.lookupOne(expected.getMountingPoint());
   assertEquals(actual.getMountingPoint(), expected.getMountingPoint());
 }
  @Test
  public void test()
      throws ApplicationAlreadyRegisteredException, WrongApplicationIdException,
          SpaceAlreadyRegisteredException, IllegalArgumentException {

    Set<SpaceInstanceInfo> spaces = new HashSet<SpaceInstanceInfo>();
    Set<Long> appsRegistered;

    spaces.add(spaceInstanceInput1);
    spaces.add(spaceInstanceInput2);
    spaces.add(spaceInstanceOutput1);
    spaces.add(spaceInstanceOutput2);

    assertFalse(stub.isApplicationIdRegistered(MAIN_APPID));
    // TEST REGISTER APP
    logger.info("Test register application");
    stub.registerApplication(MAIN_APPID, spaces);

    // check if everything has been registered
    logger.info("Checking that application has been registered");
    assertTrue(stub.isApplicationIdRegistered(MAIN_APPID));
    appsRegistered = stub.getRegisteredApplications();
    appsRegistered.contains(MAIN_APPID);

    // TEST LOOKUP FIRST
    logger.info("Test Lookup First");
    assertIsSpaceRegistered(spaceInstanceInput1);
    assertIsSpaceRegistered(spaceInstanceInput2);
    assertIsSpaceRegistered(spaceInstanceOutput1);
    assertIsSpaceRegistered(spaceInstanceOutput2);

    // TEST LOOKUP ALL
    logger.info("Test Lookup All");
    final DataSpacesURI query = DataSpacesURI.createURI(MAIN_APPID);
    final Set<SpaceInstanceInfo> actual = stub.lookupMany(query);
    assertEquals(spaces, actual);

    // TEST UNREGISTER
    logger.info("Test unregister");
    assertTrue(stub.unregister(spaceInstanceInput1.getMountingPoint()));
    assertTrue(stub.unregister(spaceInstanceOutput1.getMountingPoint()));

    // TEST LOOKUP FIRST WITH NULL ANSWER
    logger.info("Test looup first with null answer");
    assertIsSpaceUnregistered(spaceInstanceInput1);
    assertIsSpaceUnregistered(spaceInstanceOutput1);

    // TEST REGISTER
    logger.info("Test register");
    stub.register(spaceInstanceInput1);
    stub.register(spaceInstanceOutput1);

    // TEST EXCEPTION WHEN SPACE ALREADY REGISTERED
    logger.info("Test Exception when space already registered");
    try {
      stub.register(spaceInstanceInput1);
      fail("Exception expected");
    } catch (SpaceAlreadyRegisteredException e) {
    } catch (Exception e) {
      fail("Expected exception of different type");
    }

    // TEST EXCEPTION WHEN APP NOT REGISTERED
    logger.info("Test Exception when app not registered");
    try {
      stub.register(spaceInstanceInput1b);
      fail("Exception expected");
    } catch (WrongApplicationIdException e) {
    } catch (Exception e) {
      fail("Expected exception of different type");
    }

    // TEST EXCEPTION WHEN APP ALREADY REGISTERED
    logger.info("Test Exception when app already registered");
    try {
      stub.registerApplication(MAIN_APPID, null);
      fail("Exception expected");
    } catch (ApplicationAlreadyRegisteredException e) {
    } catch (Exception e) {
      fail("Expected exception of different type");
    }

    // TEST UNREGISTER APP
    logger.info("Test unregister");
    stub.unregisterApplication(MAIN_APPID);
  }
  /**
   * Mounts the first available VFS file system on the given dataspace
   *
   * @param spaceInfo space information
   * @throws FileSystemException if no file system could be mounted
   */
  private void mountFirstAvailableFileSystem(final SpaceInstanceInfo spaceInfo)
      throws FileSystemException {

    final DataSpacesURI mountingPoint = spaceInfo.getMountingPoint();

    try {
      writeLock.lock();
      if (!mountedSpaces.containsKey(mountingPoint)) {
        mountedSpaces.put(mountingPoint, new ConcurrentHashMap<String, FileObject>());
      }
      ConcurrentHashMap<String, FileObject> fileSystems = mountedSpaces.get(mountingPoint);

      if (spaceInfo.getUrls().size() == 0) {
        throw new IllegalStateException("Empty Space configuration");
      }

      DataSpacesURI spacePart = mountingPoint.getSpacePartOnly();
      ArrayList<String> urls = new ArrayList<String>(spaceInfo.getUrls());
      if (urls.size() == 1) {
        urls.add(
            0, Utils.getLocalAccessURL(urls.get(0), spaceInfo.getPath(), spaceInfo.getHostname()));
      }

      logger.debug("[VFSMountManager] Request mounting VFS root list : " + urls);

      try {
        VFSMountManagerHelper.mountAny(urls, fileSystems);

        if (!accessibleFileObjectUris.containsKey(mountingPoint)) {
          LinkedHashSet<String> srl = new LinkedHashSet<String>();
          accessibleFileObjectUris.put(mountingPoint, srl);
        }

        LinkedHashSet<String> srl = accessibleFileObjectUris.get(mountingPoint);

        for (String uri : urls) {
          if (fileSystems.containsKey(uri)) {
            srl.add(uri);
          }
        }
        if (srl.isEmpty()) {
          throw new IllegalStateException(
              "Invalid empty size list when trying to mount "
                  + urls
                  + " mounted map content is "
                  + fileSystems);
        }
        accessibleFileObjectUris.put(mountingPoint, srl);

        if (logger.isDebugEnabled())
          logger.debug(
              String.format(
                  "[VFSMountManager] Mounted space: %s (access URL: %s)", spacePart, srl));

        mountedSpaces.put(mountingPoint, fileSystems);

      } catch (org.apache.commons.vfs.FileSystemException e) {
        mountedSpaces.remove(mountingPoint);
        throw new FileSystemException(
            "An error occurred while trying to mount " + spaceInfo.getName(), e);
      }
    } finally {
      writeLock.unlock();
    }
  }