/** * Returns the preference node associated with this request. This method controls exactly what * preference nodes are exposed via this service. If there is no matching preference node for the * request, this method handles the appropriate response and returns <code>null</code>. * * @param req * @param resp * @param create If <code>true</code>, the node will be created if it does not already exist. If * <code>false</code>, this method sets the response status to 404 and returns null. */ private IEclipsePreferences getNode( HttpServletRequest req, HttpServletResponse resp, boolean create) throws ServletException { if (prefRoot == null) { handleException(resp, "Unable to obtain preference service", null); return null; } String pathString = req.getPathInfo(); if (pathString == null) pathString = ""; // $NON-NLS-1$ IPath path = new Path(pathString); int segmentCount = path.segmentCount(); String scope = path.segment(0); // note that the preference service API scope names don't match those used in our persistence // layer. IPath nodePath = null; if ("user".equalsIgnoreCase(scope)) { // $NON-NLS-1$ String username = req.getRemoteUser(); if (username == null) { resp.setStatus(HttpServletResponse.SC_FORBIDDEN); return null; } nodePath = new Path("Users").append(username); // $NON-NLS-1$ } else if ("workspace".equalsIgnoreCase(scope) && segmentCount > 1) { // $NON-NLS-1$ nodePath = new Path("Workspaces"); // $NON-NLS-1$ } else if ("project".equalsIgnoreCase(scope) && segmentCount > 1) { // $NON-NLS-1$ nodePath = new Path("Projects"); // $NON-NLS-1$ } else { // invalid prefix handleNotFound(req, resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED); return null; } // we allow arbitrary subtrees beneath our three supported roots if (nodePath != null) { String childPath = nodePath.append(path.removeFirstSegments(1)).toString(); try { if (create || prefRoot.nodeExists(childPath)) return (IEclipsePreferences) prefRoot.node(childPath); } catch (BackingStoreException e) { String msg = NLS.bind("Error retrieving preferences for path {0}", pathString); handleException( resp, new Status(IStatus.ERROR, Activator.PI_SERVER_SERVLETS, msg), HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return null; } } handleNotFound(req, resp, HttpServletResponse.SC_NOT_FOUND); return null; }
private boolean handlePost( HttpServletRequest request, HttpServletResponse response, String pathString) throws IOException, JSONException, ServletException, URISyntaxException, CoreException, NoHeadException, NoMessageException, ConcurrentRefUpdateException, WrongRepositoryStateException { // make sure required fields are set JSONObject toAdd = OrionServlet.readJSONRequest(request); if (toAdd.optBoolean(GitConstants.KEY_PULL, false)) { GitUtils.createGitCredentialsProvider(toAdd); GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd); boolean force = toAdd.optBoolean(GitConstants.KEY_FORCE, false); return pull(request, response, cp, pathString, force); } Clone clone = new Clone(); String url = toAdd.optString(GitConstants.KEY_URL, null); // method handles repository clone or just repository init // decision is based on existence of GitUrl argument boolean initOnly; if (url == null || url.isEmpty()) initOnly = true; else { initOnly = false; if (!validateCloneUrl(url, request, response)) return true; clone.setUrl(new URIish(url)); } String cloneName = toAdd.optString(ProtocolConstants.KEY_NAME, null); if (cloneName == null) cloneName = request.getHeader(ProtocolConstants.HEADER_SLUG); // expected path /workspace/{workspaceId} String workspacePath = toAdd.optString(ProtocolConstants.KEY_LOCATION, null); // expected path /file/{workspaceId}/{projectName}[/{path}] String filePathString = toAdd.optString(ProtocolConstants.KEY_PATH, null); IPath filePath = filePathString == null ? null : new Path(filePathString); if (filePath != null && filePath.segmentCount() < 3) filePath = null; if (filePath == null && workspacePath == null) { String msg = NLS.bind( "Either {0} or {1} should be provided: {2}", new Object[] {ProtocolConstants.KEY_PATH, ProtocolConstants.KEY_LOCATION, toAdd}); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } // only during init operation filePath or cloneName must be provided // during clone operation, name can be obtained from URL if (initOnly && filePath == null && cloneName == null) { String msg = NLS.bind( "Either {0} or {1} should be provided: {2}", new Object[] {ProtocolConstants.KEY_PATH, GitConstants.KEY_NAME, toAdd}); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } if (!validateCloneName(cloneName, request, response)) return true; // prepare the WebClone object, create a new project if necessary WebProject webProject = null; boolean webProjectExists = false; if (filePath != null) { // path format is /file/{workspaceId}/{projectName}/[filePath] clone.setId(filePath.toString()); webProject = GitUtils.projectFromPath(filePath); // workspace path format needs to be used if project does not exist if (webProject == null) { String msg = NLS.bind("Specified project does not exist: {0}", filePath.segment(2)); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } webProjectExists = true; clone.setContentLocation( webProject.getProjectStore().getFileStore(filePath.removeFirstSegments(3)).toURI()); if (cloneName == null) cloneName = filePath.segmentCount() > 2 ? filePath.lastSegment() : webProject.getName(); } else if (workspacePath != null) { IPath path = new Path(workspacePath); // TODO: move this to CloneJob // if so, modify init part to create a new project if necessary WebWorkspace workspace = WebWorkspace.fromId(path.segment(1)); String id = WebProject.nextProjectId(); if (cloneName == null) cloneName = new URIish(url).getHumanishName(); cloneName = getUniqueProjectName(workspace, cloneName); webProjectExists = false; webProject = WebProject.fromId(id); webProject.setName(cloneName); try { WorkspaceResourceHandler.computeProjectLocation(request, webProject, null, false); } catch (CoreException e) { // we are unable to write in the platform location! String msg = NLS.bind( "Server content location could not be written: {0}", Activator.getDefault().getRootLocationURI()); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e)); } catch (URISyntaxException e) { // should not happen, we do not allow linking at this point } try { // If all went well, add project to workspace WorkspaceResourceHandler.addProject(request.getRemoteUser(), workspace, webProject); } catch (CoreException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error persisting project state", e)); } URI baseLocation = getURI(request); baseLocation = new URI( baseLocation.getScheme(), baseLocation.getUserInfo(), baseLocation.getHost(), baseLocation.getPort(), workspacePath, baseLocation.getQuery(), baseLocation.getFragment()); clone.setId(GitUtils.pathFromProject(workspace, webProject).toString()); clone.setContentLocation(webProject.getProjectStore().toURI()); } clone.setName(cloneName); clone.setBaseLocation(getURI(request)); JSONObject cloneObject = clone.toJSON(); String cloneLocation = cloneObject.getString(ProtocolConstants.KEY_LOCATION); if (initOnly) { // git init InitJob job = new InitJob( clone, TaskJobHandler.getUserId(request), request.getRemoteUser(), cloneLocation); return TaskJobHandler.handleTaskJob(request, response, job, statusHandler); } // git clone // prepare creds GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd); cp.setUri(new URIish(clone.getUrl())); // if all went well, clone CloneJob job = new CloneJob( clone, TaskJobHandler.getUserId(request), cp, request.getRemoteUser(), cloneLocation, webProjectExists ? null : webProject /* used for cleaning up, so null when not needed */); return TaskJobHandler.handleTaskJob(request, response, job, statusHandler); }
private boolean handleGet( HttpServletRequest request, HttpServletResponse response, String pathString) throws IOException, JSONException, ServletException, URISyntaxException, CoreException { IPath path = pathString == null ? Path.EMPTY : new Path(pathString); URI baseLocation = getURI(request); String user = request.getRemoteUser(); // expected path format is 'workspace/{workspaceId}' or // 'file/{workspaceId}/{projectName}/{path}]' if ("workspace".equals(path.segment(0)) && path.segmentCount() == 2) { // $NON-NLS-1$ // all clones in the workspace if (WebWorkspace.exists(path.segment(1))) { WebWorkspace workspace = WebWorkspace.fromId(path.segment(1)); JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); for (WebProject webProject : workspace.getProjects()) { // this is the location of the project metadata if (isAccessAllowed(user, webProject)) { IPath projectPath = GitUtils.pathFromProject(workspace, webProject); Map<IPath, File> gitDirs = GitUtils.getGitDirs(projectPath, Traverse.GO_DOWN); for (Map.Entry<IPath, File> entry : gitDirs.entrySet()) { children.put(new Clone().toJSON(entry, baseLocation)); } } } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } else if ("file".equals(path.segment(0)) && path.segmentCount() > 1) { // $NON-NLS-1$ // clones under given path WebProject webProject = GitUtils.projectFromPath(path); IPath projectRelativePath = path.removeFirstSegments(3); if (webProject != null && isAccessAllowed(user, webProject) && webProject.getProjectStore().getFileStore(projectRelativePath).fetchInfo().exists()) { Map<IPath, File> gitDirs = GitUtils.getGitDirs(path, Traverse.GO_DOWN); JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); for (Map.Entry<IPath, File> entry : gitDirs.entrySet()) { children.put(new Clone().toJSON(entry, baseLocation)); } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } // else the request is malformed String msg = NLS.bind("Invalid clone request: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); }