/** @see org.jlibrary.core.repository.RepositoryService#exportRepository(Ticket) */
  public byte[] exportRepository(Ticket ticket)
      throws RepositoryNotFoundException, RepositoryException, SecurityException {

    try {
      javax.jcr.Session session = SessionManager.getInstance().getSession(ticket);
      if (session == null) {
        throw new RepositoryException("Session has expired. Please log in again.");
      }
      javax.jcr.Node root = JCRUtils.getRootNode(session);
      if (!JCRSecurityService.canRead(root, ticket.getUser().getId())) {
        throw new SecurityException(SecurityException.NOT_ENOUGH_PERMISSIONS);
      }

      ByteArrayOutputStream baos1 = null;
      byte[] rootContent;
      try {
        baos1 = new ByteArrayOutputStream();
        session.exportSystemView(JCRUtils.getRootNode(session).getPath(), baos1, false, false);
        rootContent = baos1.toByteArray();
      } finally {
        if (baos1 != null) {
          baos1.close();
        }
      }
      byte[] systemContent;
      ByteArrayOutputStream baos2 = null;
      try {
        baos2 = new ByteArrayOutputStream();
        session.exportSystemView(JCRUtils.getSystemNode(session).getPath(), baos2, false, false);
        systemContent = baos2.toByteArray();
      } finally {
        if (baos2 != null) {
          baos2.close();
        }
      }

      String tag = String.valueOf(rootContent.length) + "*";
      byte[] header = tag.getBytes();

      byte[] content = new byte[header.length + rootContent.length + systemContent.length];
      System.arraycopy(header, 0, content, 0, header.length);
      System.arraycopy(rootContent, 0, content, header.length, rootContent.length);
      System.arraycopy(
          systemContent, 0, content, header.length + rootContent.length, systemContent.length);

      return zipContent(content);
    } catch (PathNotFoundException e) {
      logger.error(e.getMessage(), e);
      throw new RepositoryException(e);
    } catch (IOException e) {
      logger.error(e.getMessage(), e);
      throw new RepositoryException(e);
    } catch (javax.jcr.RepositoryException 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);
    }
  }
  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 exportRepository(Ticket ticket, OutputStream stream)
      throws RepositoryNotFoundException, RepositoryException, SecurityException {

    try {
      javax.jcr.Session session = SessionManager.getInstance().getSession(ticket);
      if (session == null) {
        throw new RepositoryException("Session has expired. Please log in again.");
      }
      javax.jcr.Node root = JCRUtils.getRootNode(session);
      if (!JCRSecurityService.canRead(root, ticket.getUser().getId())) {
        throw new SecurityException(SecurityException.NOT_ENOUGH_PERMISSIONS);
      }

      // Create a temporary file with content
      File tempRoot = File.createTempFile("tmp", "jlib");
      FileOutputStream fos = null;
      try {
        fos = new FileOutputStream(tempRoot);
        session.exportSystemView(JCRUtils.getRootNode(session).getPath(), fos, false, false);
      } finally {
        if (fos != null) {
          fos.close();
        }
      }

      // Will wrap compression around the given stream
      ZipOutputStream zos = null;
      try {
        zos = new ZipOutputStream(stream);
        zos.setComment("jLibrary ZIP archive");
        zos.setMethod(ZipOutputStream.DEFLATED);
        zos.setEncoding("UTF-8");
        zos.setLevel(Deflater.DEFAULT_COMPRESSION);

        // create and initialize a zipentry for it
        ZipEntry entry = new ZipEntry("jlibrary");
        entry.setTime(System.currentTimeMillis());
        zos.putNextEntry(entry);
        // write header
        String tag = String.valueOf(tempRoot.length()) + "*";
        byte[] header = tag.getBytes();
        zos.write(header);

        // write root
        FileInputStream fis = null;
        try {
          fis = new FileInputStream(tempRoot);
          IOUtils.copy(fis, zos);
        } finally {
          if (fis != null) {
            fis.close();
          }
        }
        // Delete root file
        tempRoot.delete();

        session.exportSystemView(JCRUtils.getSystemNode(session).getPath(), zos, false, false);
      } finally {
        if (zos != null) {
          zos.closeEntry();
          zos.close();
        }
      }

    } catch (PathNotFoundException e) {
      logger.error(e.getMessage(), e);
      throw new RepositoryException(e);
    } catch (IOException e) {
      logger.error(e.getMessage(), e);
      throw new RepositoryException(e);
    } catch (javax.jcr.RepositoryException e) {
      logger.error(e.getMessage(), e);
      throw new RepositoryException(e);
    }
  }