/**
  * Make sure the specified project has been loaded and is available for use. Checks logged user
  * too. Also the loaded project is placed in the activeProject variable
  *
  * @param projectName
  * @return
  * @throws StorageException, WebApplicationException/unauthorized
  * @throws ProjectDoesNotExist
  */
 void assertProjectAvailable(String projectName) throws StorageException, ProjectDoesNotExist {
   if (!FsProjectStorage.projectExists(projectName, workspaceStorage))
     throw new ProjectDoesNotExist("Project " + projectName + " does not exist");
   ProjectState project = FsProjectStorage.loadProject(projectName, workspaceStorage);
   if (project.getHeader().getOwner() != null) {
     // needs further checking
     if (securityContext.getUserPrincipal() != null) {
       String loggedUser = securityContext.getUserPrincipal().getName();
       if (loggedUser.equals(project.getHeader().getOwner())) {
         this.activeProject = project;
         return;
       }
     }
     throw new WebApplicationException(Response.Status.UNAUTHORIZED);
   }
   activeProject = project;
 }
 @RvdAuth
 @GET
 @Path("{name}/settings")
 public Response getProjectSettings(@PathParam("name") String name) {
   try {
     ProjectSettings projectSettings =
         FsProjectStorage.loadProjectSettings(name, workspaceStorage);
     return Response.ok(marshaler.toData(projectSettings)).build();
   } catch (StorageEntityNotFound e) {
     return Response.status(Status.NOT_FOUND).build();
   } catch (StorageException e) {
     logger.error(e, e);
     return Response.status(Status.INTERNAL_SERVER_ERROR).build();
   }
 }
 @RvdAuth
 @POST
 @Path("{name}/settings")
 public Response saveProjectSettings(@PathParam("name") String name) {
   logger.info("saving project settings for " + name);
   String data;
   try {
     data = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8"));
     ProjectSettings projectSettings = marshaler.toModel(data, ProjectSettings.class);
     FsProjectStorage.storeProjectSettings(projectSettings, name, workspaceStorage);
     return Response.ok().build();
   } catch (StorageException e) {
     logger.error(e, e);
     return Response.status(Status.INTERNAL_SERVER_ERROR).build();
   } catch (IOException e) {
     logger.error(e, e);
     return Response.status(Status.INTERNAL_SERVER_ERROR).build();
   }
 }
 /*
  * Return a wav file from the project. It's the same as getWav() but it has the Query parameters converted to Path
  * parameters
  */
 @GET
 @Path("{name}/wavs/{filename}.wav")
 public Response getWavNoQueryParams(
     @PathParam("name") String projectName, @PathParam("filename") String filename) {
   InputStream wavStream;
   try {
     wavStream = FsProjectStorage.getWav(projectName, filename + ".wav", workspaceStorage);
     return Response.ok(wavStream, "audio/x-wav")
         .header("Content-Disposition", "attachment; filename = " + filename)
         .build();
   } catch (WavItemDoesNotExist e) {
     return Response.status(Status.NOT_FOUND)
         .build(); // ordinary error page is returned since this will be consumed
     // either from restcomm or directly from user
   } catch (StorageException e) {
     // return buildErrorResponse(Status.INTERNAL_SERVER_ERROR, RvdResponse.Status.ERROR, e);
     return Response.status(Status.INTERNAL_SERVER_ERROR)
         .build(); // ordinary error page is returned since this will be
     // consumed either from restcomm or directly from user
   }
 }
 @RvdAuth
 @POST
 @Path("{name}")
 public Response updateProject(
     @Context HttpServletRequest request, @PathParam("name") String projectName) {
   if (projectName != null && !projectName.equals("")) {
     logger.info("Saving project " + projectName);
     try {
       ProjectState existingProject = FsProjectStorage.loadProject(projectName, workspaceStorage);
       Principal loggedUser = securityContext.getUserPrincipal();
       if (loggedUser.getName().equals(existingProject.getHeader().getOwner())
           || existingProject.getHeader().getOwner() == null) {
         projectService.updateProject(request, projectName, existingProject);
         return buildOkResponse();
       } else {
         throw new WebApplicationException(Response.Status.UNAUTHORIZED);
       }
     } catch (ValidationException e) {
       RvdResponse rvdResponse = new RvdResponse().setValidationException(e);
       return Response.status(Status.OK).entity(rvdResponse.asJson()).build();
       // return buildInvalidResponse(Status.OK, RvdResponse.Status.INVALID,e);
       // Gson gson = new Gson();
       // return Response.ok(gson.toJson(e.getValidationResult()),
       // MediaType.APPLICATION_JSON).build();
     } catch (IncompatibleProjectVersion e) {
       logger.error(e);
       return Response.status(Status.INTERNAL_SERVER_ERROR)
           .entity(e.asJson())
           .type(MediaType.APPLICATION_JSON)
           .build();
     } catch (RvdException e) {
       logger.error(e.getMessage(), e);
       return buildErrorResponse(Status.OK, RvdResponse.Status.ERROR, e);
       // return Response.status(Status.INTERNAL_SERVER_ERROR).build();
     }
   } else {
     logger.warn("Empty project name specified for updating");
     return Response.status(Status.BAD_REQUEST).build();
   }
 }
  @RvdAuth
  @POST
  // @Path("{name}/archive")
  public Response importProjectArchive(
      @Context HttpServletRequest request, @QueryParam("ticket") String ticket) {
    logger.info("Importing project from raw archive");
    ProjectApplicationsApi applicationsApi = null;
    String projectName = null;

    try {
      if (request.getHeader("Content-Type") != null
          && request.getHeader("Content-Type").startsWith("multipart/form-data")) {
        Gson gson = new Gson();
        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator iterator = upload.getItemIterator(request);

        JsonArray fileinfos = new JsonArray();

        while (iterator.hasNext()) {
          FileItemStream item = iterator.next();
          JsonObject fileinfo = new JsonObject();
          fileinfo.addProperty("fieldName", item.getFieldName());

          // is this a file part (talking about multipart requests, there might be parts that are
          // not actual files).
          // They will be ignored
          if (item.getName() != null) {
            String effectiveProjectName =
                projectService.importProjectFromArchive(item.openStream(), item.getName());
            // buildService.buildProject(effectiveProjectName);

            // Load project kind
            String projectString =
                FsProjectStorage.loadProjectString(effectiveProjectName, workspaceStorage);
            ProjectState state = marshaler.toModel(projectString, ProjectState.class);
            String projectKind = state.getHeader().getProjectKind();
            projectName = effectiveProjectName;

            // Create application
            applicationsApi =
                new ProjectApplicationsApi(servletContext, workspaceStorage, marshaler);
            applicationsApi.createApplication(ticket, effectiveProjectName, projectKind);

            fileinfo.addProperty("name", item.getName());
            fileinfo.addProperty("projectName", effectiveProjectName);
          }
          if (item.getName() == null) {
            logger.warn("non-file part found in upload");
            fileinfo.addProperty("value", read(item.openStream()));
          }
          fileinfos.add(fileinfo);
        }
        return Response.ok(gson.toJson(fileinfos), MediaType.APPLICATION_JSON).build();
      } else {
        String json_response = "{\"result\":[{\"size\":" + size(request.getInputStream()) + "}]}";
        return Response.ok(json_response, MediaType.APPLICATION_JSON).build();
      }
    } catch (StorageException e) {
      logger.warn(e, e);
      logger.debug(e, e);
      return buildErrorResponse(Status.BAD_REQUEST, RvdResponse.Status.ERROR, e);
    } catch (ApplicationAlreadyExists e) {
      logger.warn(e, e);
      logger.debug(e, e);
      try {
        applicationsApi.rollbackCreateApplication(ticket, projectName);
      } catch (ApplicationsApiSyncException e1) {
        logger.error(e1.getMessage(), e1);
        return buildErrorResponse(Status.INTERNAL_SERVER_ERROR, RvdResponse.Status.ERROR, e);
      }
      return buildErrorResponse(Status.CONFLICT, RvdResponse.Status.ERROR, e);
    } catch (Exception e /* TODO - use a more specific type !!! */) {
      logger.error(e.getMessage(), e);
      return Response.status(Status.INTERNAL_SERVER_ERROR).build();
    }
  }