/**
   * Checks if a given workspace exists
   *
   * @param name Name of the workspace to check
   * @param systemSession System session
   * @return WorkspaceImpl A WorkspaceImpl if the workspace currently exists
   * @throws javax.jcr.RepositoryException If the check cannot be done
   * @throws RepositoryAlreadyExistsException If the workspace already exists
   * @throws RecentlyRemovedRepositoryException If the workspace already exists, but has been tagged
   *     to be definitvely removed on server startup
   */
  public WorkspaceImpl checkWorkspaceExists(String name, Session systemSession)
      throws javax.jcr.RepositoryException, RepositoryAlreadyExistsException,
          RecentlyRemovedRepositoryException {

    WorkspaceImpl workspace = (WorkspaceImpl) systemSession.getWorkspace();
    String[] names = workspace.getAccessibleWorkspaceNames();
    for (int i = 0; i < names.length; i++) {
      if (names[i].equals(name)) {
        // Ok, check if it was scheduled for remove
        if (JCRCleanupModule.isScheduledForDelete(systemSession, name)) {
          throw new RecentlyRemovedRepositoryException();
        }
        throw new RepositoryAlreadyExistsException();
      }
    }
    return workspace;
  }
  public void importRepository(Ticket ticket, String name, InputStream inputStream)
      throws RepositoryAlreadyExistsException, RepositoryException, SecurityException {

    try {

      if (!ticket.getUser().isAdmin()) {
        throw new SecurityException(SecurityException.NOT_ENOUGH_PERMISSIONS);
      }

      javax.jcr.Session systemSession = SessionManager.getInstance().getSystemSession(ticket);
      WorkspaceImpl workspace = checkWorkspaceExists(name, systemSession);
      // Always change to lowercase
      name = name.toLowerCase();
      workspace.createWorkspace(name);

      javax.jcr.Repository repository = SessionManager.getInstance().getRepository();
      SimpleCredentials creds = new SimpleCredentials("username", "password".toCharArray());

      systemSession = repository.login(creds, name);

      // Copy to temp file. We cannot wrap to zip input stream due to incompatibilities
      // between apache implementation and java.util implementation
      File tempFile = File.createTempFile("jlib", "tmp");
      tempFile.deleteOnExit();
      FileOutputStream fos = new FileOutputStream(tempFile);
      IOUtils.copy(inputStream, fos);
      fos.flush();
      fos.close();

      ZipFile archive = null;
      try {
        archive = new ZipFile(tempFile);
      } catch (IOException ioe) {
        logger.warn("[JCRImportService] Trying to import non zipped repository");
        // probably this will be an old repository, so we will return the
        // content to let the process try to import it
        return;
      }

      // do our own buffering; reuse the same buffer.
      byte[] buffer = new byte[16384];
      ZipEntry entry = archive.getEntry("jlibrary");

      // get a stream of the archive entry's bytes
      InputStream zis = archive.getInputStream(entry);

      // ZipInputStream zis = new ZipInputStream(inputStream);
      byte[] smallBuffer = new byte[32];
      int i = 0;
      boolean tagFound = false;
      while (!tagFound) {
        byte next = (byte) zis.read();
        if (next == '*') {
          tagFound = true;
        } else {
          smallBuffer[i] = next;
          i++;
        }
      }

      byte[] header = new byte[i];
      System.arraycopy(smallBuffer, 0, header, 0, i);
      String lengthString = new String(header);
      int contentLength = Integer.parseInt(lengthString.substring(0, lengthString.length()));

      InputStream wrapzis = new ImportInputStream(zis, contentLength);
      systemSession.importXML("/", wrapzis, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);

      // Reopen the stream. importXML closes it
      zis = archive.getInputStream(entry);
      zis.skip(i + 1 + contentLength);

      // Now import the remaining info
      systemSession.importXML("/", zis, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);

      tempFile.delete();

      checkCustomProperties(systemSession);

      systemSession.save();

      // Finally check versions compatibility
      VersionChecker checker = new VersionChecker();
      checker.checkSession(systemSession);
    } catch (ConfigurationException ce) {
      // TODO: Remove this catch block when Jackrabbit supports workspace deletes
      throw new RecentlyRemovedRepositoryException();
    } catch (RepositoryAlreadyExistsException raee) {
      throw raee;
    } catch (SecurityException se) {
      throw se;
    } catch (AccessDeniedException e) {
      logger.error(e.getMessage(), e);
      throw new SecurityException(e);
    } catch (LoginException e) {
      logger.error(e.getMessage(), e);
      throw new SecurityException(e);
    } catch (RepositoryException re) {
      throw re;
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new RepositoryException(e);
    }
  }
  public void importRepository(Ticket ticket, byte[] zippedContent, String name)
      throws RepositoryAlreadyExistsException, RepositoryException, SecurityException {

    try {

      if (!ticket.getUser().isAdmin()) {
        throw new SecurityException(SecurityException.NOT_ENOUGH_PERMISSIONS);
      }

      javax.jcr.Session systemSession = SessionManager.getInstance().getSystemSession(ticket);
      WorkspaceImpl workspace = checkWorkspaceExists(name, systemSession);
      // Always change to lowercase
      name = name.toLowerCase();
      workspace.createWorkspace(name);

      javax.jcr.Repository repository = SessionManager.getInstance().getRepository();
      SimpleCredentials creds = new SimpleCredentials("username", "password".toCharArray());

      systemSession = repository.login(creds, name);

      byte[] content = unzipContent(zippedContent);

      // First read the header
      int i = 0;
      while (content[i] != '*') {
        i++;
      }
      i++;
      byte[] header = new byte[i];
      System.arraycopy(content, 0, header, 0, i);
      String lengthString = new String(header);
      int contentLength = Integer.parseInt(lengthString.substring(0, lengthString.length() - 1));

      // Now, load root content

      byte[] rootContent = new byte[contentLength];
      System.arraycopy(content, i, rootContent, 0, contentLength);
      rootContent = filterForCompatibility(rootContent);
      ByteArrayInputStream bais1 = new ByteArrayInputStream(rootContent);

      // Now load system content
      byte[] systemContent = new byte[content.length - contentLength - header.length];
      System.arraycopy(
          content, header.length + contentLength, systemContent, 0, systemContent.length);
      systemContent = filterForCompatibility(systemContent);
      ByteArrayInputStream bais2 = new ByteArrayInputStream(systemContent);

      systemSession.importXML("/", bais1, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);

      systemSession.importXML("/", bais2, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);

      checkCustomProperties(systemSession);

      bais1.close();
      bais2.close();

      systemSession.save();

      // Finally check versions compatibility
      VersionChecker checker = new VersionChecker();
      checker.checkSession(systemSession);
    } catch (ConfigurationException ce) {
      // TODO: Remove this catch block when Jackrabbit supports workspace deletes
      throw new RecentlyRemovedRepositoryException();
    } catch (RepositoryAlreadyExistsException raee) {
      throw raee;
    } catch (SecurityException se) {
      throw se;
    } catch (AccessDeniedException e) {
      logger.error(e.getMessage(), e);
      throw new SecurityException(e);
    } catch (LoginException e) {
      logger.error(e.getMessage(), e);
      throw new SecurityException(e);
    } catch (RepositoryException re) {
      throw re;
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new RepositoryException(e);
    }
  }