--- /dev/null
+package com.pentila.entSavoie.edx;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.text.Normalizer;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.net.ssl.HttpsURLConnection;
+
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import com.liferay.portal.kernel.exception.PortalException;
+import com.liferay.portal.kernel.exception.SystemException;
+import com.liferay.portal.kernel.json.JSONArray;
+import com.liferay.portal.kernel.json.JSONException;
+import com.liferay.portal.kernel.json.JSONFactoryUtil;
+import com.liferay.portal.kernel.json.JSONObject;
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+import com.liferay.portal.model.Role;
+import com.liferay.portal.model.User;
+import com.liferay.portal.service.RoleLocalServiceUtil;
+import com.pentila.entSavoie.ENTRolesConstants;
+import com.pentila.entSavoie.edx.model.EdxCourse;
+import com.pentila.entSavoie.edx.model.EdxUser;
+import com.pentila.entSavoie.edx.service.EdxCourseLocalServiceUtil;
+import com.pentila.entSavoie.edx.service.EdxUserLocalServiceUtil;
+import com.pentila.entSavoie.utils.ENTMainUtilsLocalServiceUtil;
+
+public class EdxWebServiceUtil {
+
+ private static final String USER_AGENT = "Mozilla/5.0";
+ private static final String EDX_BASE_URL = ENTMainUtilsLocalServiceUtil.getEdxBaseUrl();
+ private static final String EDX_USER_CREATION_URL = "/user_api/v1/account/registration/";
+ private static final String EDX_USER_ENROLLMENT_URL = "/api/enrollment/v1/enrollment";
+ private static final String EDX_COURSES_URL = "/api/courses/v1/courses";
+ private static final String EDX_BLOCKS_URL = "/api/courses/v1/blocks/";
+
+ private static final String ACCESS_TOKEN = "Bearer " + ENTMainUtilsLocalServiceUtil.getEdxAccessToken();
+ private static final int MAX_USERNAME_LENGTH = 30;
+ private static final int HTTP_CODE_OK = 200;
+
+ private static Log _log = LogFactoryUtil.getLog(EdxWebServiceUtil.class);
+
+ /**
+ * Update the list of teacher courses
+ *
+ * @param edxUserId
+ * @throws IOException
+ * @throws PortalException
+ * @throws SystemException
+ */
+ public static void updateTeacherCourses(User teacher) throws IOException, PortalException, SystemException {
+
+ JSONArray coursesList = JSONFactoryUtil.createJSONArray();
+ final String dateFormat = "yyyy-MM-dd'T'hh:mm:ss'Z'";
+
+ // Get teacher's edx username
+ EdxUser edxUser = EdxUserLocalServiceUtil.getEdxUser(teacher.getUserId());
+ if (edxUser == null) {
+ _log.error("Teacher " + teacher.getFullName() + " does not exist in database");
+ return;
+ }
+
+ String url = EDX_BASE_URL + EDX_COURSES_URL + "/?org=" + edxUser.getEdxUsername();
+
+ try {
+ do {
+ String response = sendGet(url);
+ if (response.equals("")) {
+ _log.error("Error : http get request to update teacher courses returns response " + response);
+ return;
+ }
+ JSONObject jsonResponse = parseDjangoApiResponse(response);
+
+ JSONArray coursesListTmp = jsonResponse.getJSONArray("results");
+ for (int i = 0; i < coursesListTmp.length(); i++) {
+ coursesList.put(coursesListTmp.getJSONObject(i));
+ }
+ if (jsonResponse.has("pagination") && jsonResponse.getJSONObject("pagination").has("next")
+ && !jsonResponse.getJSONObject("pagination").getString("next").isEmpty()) {
+ url = jsonResponse.getJSONObject("pagination").getString("next");
+ } else {
+ url = "";
+ }
+ } while (!url.trim().isEmpty());
+
+ _log.info("Parsed " + coursesList.length() + " courses");
+
+ for (int i = 0; i < coursesList.length(); i++) {
+ JSONObject jsonCourse = coursesList.getJSONObject(i);
+ String courseId = jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_COURSE_ID);
+ _log.info("Found course_id " + courseId);
+
+ // Keep only courses with teacher's name in it
+ // This is due to hack done in edx that hardcodes the course's
+ // organization name as the teacher username
+ if (courseId.contains(edxUser.getEdxUsername())) {
+
+ // Parse course informations
+ EdxCourse edxCourse = EdxCourseLocalServiceUtil.addTeacherCourse(teacher.getUserId(),
+ jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_COURSE_ID));
+ edxCourse.setCourseName(jsonCourse.getString("name"));
+ if (!jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_START).equals("")) {
+ Date courseStartDate = new SimpleDateFormat(dateFormat)
+ .parse(jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_START));
+ edxCourse.setCourseStartDate(courseStartDate);
+ }
+ if (!jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_ENROLLMENT_START).equals("")) {
+ Date enrollMentStartDate = new SimpleDateFormat(dateFormat)
+ .parse(jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_ENROLLMENT_START));
+ edxCourse.setEnrollmentStartDate(enrollMentStartDate);
+ }
+ if (!jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_ENROLLMENT_END).equals("")) {
+ Date enrollmentEndDate = new SimpleDateFormat(dateFormat)
+ .parse(jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_ENROLLMENT_END));
+ edxCourse.setEnrollmentEndDate(enrollmentEndDate);
+ }
+ edxCourse.setDescription(jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_SHORT_DESC));
+ edxCourse.setNumber(jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_NUMBER));
+ EdxCourseLocalServiceUtil.updateEdxCourse(edxCourse);
+
+ synchronizeCourse(jsonCourse.getString(EdxConstants.EDX_API_TEACHER_COURSE_COURSE_ID));
+ _log.info("Synchronized course structure");
+
+ }
+
+ }
+
+ } catch (Exception e) {
+ _log.error("Error when getting the list of courses", e);
+ }
+
+ }
+
+ /**
+ * Enroll a student in a course
+ *
+ * @param student
+ * @param courseId
+ * @return
+ */
+ public static boolean enrollStudentInCourse(User student, String courseId) {
+
+ // Create edx user if it does not already exist
+ EdxUser edxUser = null;
+ try {
+ edxUser = EdxUserLocalServiceUtil.getEdxUser(student.getUserId());
+ } catch (Exception e) {
+ _log.error("Error when getting edx user for userId " + student.getFullName());
+ }
+ if (edxUser == null) {
+ try {
+ edxUser = createUserInEdx(student);
+ } catch (Exception e) {
+ _log.error("Error when creating edx user for userId " + student.getFullName());
+ }
+ }
+
+ // Now enroll the student into the course
+ String wsUrl = EDX_BASE_URL + EDX_USER_ENROLLMENT_URL;
+
+ JSONObject courseDetails = JSONFactoryUtil.createJSONObject();
+ courseDetails.put(EdxConstants.EDX_API_ENROLL_COURSE_ID, courseId);
+ JSONObject json = JSONFactoryUtil.createJSONObject();
+ json.put(EdxConstants.EDX_API_ENROLL_USER, edxUser.getEdxUsername());
+ json.put(EdxConstants.EDX_API_ENROLL_COURSE_DETAILS, courseDetails);
+ try {
+ String postResponse = sendJsonPost(wsUrl, json.toString());
+
+ // Parse returned json to check student's enrollment
+ return checkUserEnrollment(postResponse, courseId);
+ } catch (Exception e) {
+ _log.error("Error when enrolling student " + student.getFullName() + " in course " + courseId, e);
+ }
+ return false;
+ }
+
+ /**
+ * Create a user in the edx mapping table
+ *
+ * @param user
+ * @return the created user
+ * @throws Exception
+ */
+ public static EdxUser createUserInEdx(User user) throws Exception {
+ //find user role
+ Role nat1Role = RoleLocalServiceUtil.getRole(user.getCompanyId(), ENTRolesConstants.NATIONAL_1);
+ Role nat2Role = RoleLocalServiceUtil.getRole(user.getCompanyId(), ENTRolesConstants.NATIONAL_2);
+ Role nat3Role = RoleLocalServiceUtil.getRole(user.getCompanyId(), ENTRolesConstants.NATIONAL_3);
+ Role nat4Role = RoleLocalServiceUtil.getRole(user.getCompanyId(), ENTRolesConstants.NATIONAL_4);
+
+ // Send post request
+ String wsUrl = EDX_BASE_URL + EDX_USER_CREATION_URL;
+
+ List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_EMAIL, user.getEmailAddress()));
+
+ String username = buildUserName(user);
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_USERNAME, username));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_NAME,
+ user.getLastName() + " " + user.getFirstName()));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_FIRSTNAME, user.getFirstName()));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_LASTNAME, user.getLastName()));
+
+
+ if (RoleLocalServiceUtil.hasUserRole(user.getUserId(), nat1Role.getRoleId()) && RoleLocalServiceUtil.hasUserRole(user.getUserId(), nat2Role.getRoleId())){
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_ROLE, "4"));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_IS_STAFF, "0"));
+ }
+ else if(RoleLocalServiceUtil.hasUserRole(user.getUserId(), nat4Role.getRoleId())){
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_ROLE, "1"));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_IS_STAFF, "1"));
+ }
+ else if(RoleLocalServiceUtil.hasUserRole(user.getUserId(), nat3Role.getRoleId())){
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_ROLE, "3"));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_IS_STAFF, "0"));
+ }
+
+
+ // Password is a random string : 4 first letters are 'Nat3' in case of a
+ // teacher
+ // This is a hack in edx that allows to set 'is_staff' to the right
+ // value without having to update user's account through a new api call
+ String shortRole = "rand";
+ if (RoleLocalServiceUtil.hasUserRole(user.getUserId(), nat3Role.getRoleId())) {
+ shortRole = "Nat3";
+ }
+ String password = shortRole + RandomStringUtils.randomAlphanumeric(16);
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_PASSWORD, password));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_HONOR_CODE, "true"));
+ urlParameters.add(new BasicNameValuePair(EdxConstants.EDX_API_CREATE_USER_TERMS, "true"));
+ _log.info("About to create user in edx with username " + username + " and password " + password);
+
+ boolean isCreatedInEdx = false;
+ try {
+ String postResponse = "";
+ int responseCode = sendValuePairPost(wsUrl, urlParameters, postResponse);
+ if (responseCode == 200) {
+ _log.info("User creation in edx went fine for " + user.getFullName());
+ isCreatedInEdx = true;
+ } else if (responseCode == 409) {
+ _log.info("User " + user.getFullName() + " already exists in edx ");
+ isCreatedInEdx = true;
+ } else {
+ _log.info("User creation in edx is in error for " + user.getFullName() + " : post response is "
+ + postResponse);
+ }
+ } catch (Exception e) {
+ _log.error("Error when creating edx account for user " + user.getFullName(), e);
+ }
+
+ if (isCreatedInEdx) {
+ EdxUser edxUser = null;
+ try {
+ edxUser = EdxUserLocalServiceUtil.getEdxUser(user.getUserId());
+ } catch (Exception e) {
+ }
+ if (edxUser == null) {
+ edxUser = EdxUserLocalServiceUtil.createEdxUser(user.getUserId());
+ edxUser.setEdxPassword(password);
+ edxUser.setEdxUsername(username);
+ EdxUserLocalServiceUtil.updateEdxUser(edxUser);
+ }
+ return edxUser;
+ }
+ return null;
+ }
+
+ /**
+ * Parses the html response and extract the useful data into a JSON object
+ *
+ * @param response
+ * @return
+ */
+ private static JSONObject parseDjangoApiResponse(String response) {
+
+ JSONObject jsonResp = null;
+ try {
+ jsonResp = JSONFactoryUtil.createJSONObject(response);
+ } catch (JSONException e) {
+
+ }
+ if (jsonResp == null) {
+ try {
+ Document doc = Jsoup.parse(response);
+ Elements elements = doc.getElementsByAttributeValue("class", "response-info");
+ Element element = elements.get(0);
+ Element preElement = element.getElementsByTag("pre").get(0);
+ String text = preElement.text();
+ String resp = text.substring(text.indexOf("{"));
+ jsonResp = JSONFactoryUtil.createJSONObject(resp);
+ } catch (Exception e) {
+ _log.error("Error when parsing HTML response into Json structure. Html is " + response, e);
+ }
+ }
+ return jsonResp;
+ }
+
+ /**
+ * Parses the json response and extract the useful data into a JSON object
+ * Input Json string contains, for a given user, the list of courses he is
+ * enrolled in
+ *
+ * @param response
+ * @return
+ */
+ private static boolean checkUserEnrollment(String postResponse, String courseId) {
+
+ try {
+ if (postResponse.contains("does not exist")) {
+ _log.error("User does not exist !");
+ return false;
+ }
+
+ JSONObject jsonResp = JSONFactoryUtil.createJSONObject(postResponse);
+ JSONObject courseDetails = jsonResp.getJSONObject(EdxConstants.EDX_API_ENROLL_COURSE_DETAILS);
+ String returnedCourseId = courseDetails.getString(EdxConstants.EDX_API_ENROLL_COURSE_ID);
+ if (returnedCourseId.equals(courseId)) {
+ return true;
+ }
+ } catch (Exception e) {
+ _log.error("Error when parsing the usercourses json response : " + postResponse, e);
+ }
+ _log.error("User was not enrolled correctly in courseId " + courseId);
+ return false;
+ }
+
+ public static void synchronizeCourse(String courseId) {
+
+ String encodedCourseId = "";
+ try {
+ encodedCourseId = URLEncoder.encode(courseId, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ _log.error("Error when url-encoding courseId " + courseId, e);
+ }
+ if (!encodedCourseId.equals("")) {
+
+ String wsUrl = EDX_BASE_URL + EDX_BLOCKS_URL + "?course_id=" + encodedCourseId // The
+ // course
+ // id
+ + "&all_blocks=true" // Replace this parameter by 'username'
+ // parameter if we want to get all
+ // blocks for a given student
+ + "&depth=all" // Return the whole course structure
+ + "&requested_fields=children"; // The 'children' key
+ // describes the children
+ // blockIds
+ try {
+ String getResponse = sendGet(wsUrl);
+ if (getResponse.equals("")) {
+ _log.error("Http get request to get course details failed with response " + getResponse);
+ return;
+ }
+ JSONObject jsonCourseBlocks = parseDjangoApiResponse(getResponse);
+ _log.info("contenu jsonCourseBlocks " + jsonCourseBlocks);
+
+ JSONObject structuredCourse = parseCourseBlocks(jsonCourseBlocks);
+
+ // add the more information of course
+ boolean isCourseBlockInfoModified = false;
+ EdxCourse edxCourse = EdxCourseLocalServiceUtil.getEdxCourse(courseId);
+ if (!edxCourse.getDisplayName()
+ .equals(structuredCourse.getString(EdxConstants.EDX_API_BLOCKS_DISPLAY_NAME))) {
+ edxCourse.setDisplayName(structuredCourse.getString(EdxConstants.EDX_API_BLOCKS_DISPLAY_NAME));
+ isCourseBlockInfoModified = true;
+ }
+ if (!edxCourse.getLmsWebUrl()
+ .equals(structuredCourse.getString(EdxConstants.EDX_API_BLOCKS_LMS_WEB_URL))) {
+ edxCourse.setLmsWebUrl(structuredCourse.getString(EdxConstants.EDX_API_BLOCKS_LMS_WEB_URL));
+ isCourseBlockInfoModified = true;
+ }
+ if (!edxCourse.getStudentViewUrl()
+ .equals(structuredCourse.getString(EdxConstants.EDX_API_BLOCKS_STUDENT_VIEW_URL))) {
+ edxCourse.setStudentViewUrl(
+ structuredCourse.getString(EdxConstants.EDX_API_BLOCKS_STUDENT_VIEW_URL));
+ isCourseBlockInfoModified = true;
+ }
+ if (isCourseBlockInfoModified) {
+ EdxCourseLocalServiceUtil.updateEdxCourse(edxCourse, false);
+ }
+
+ EdxSynchronizationUtils.synchronizeCourseSections(courseId, structuredCourse.getJSONArray("sections"));
+ } catch (Exception e) {
+ _log.error("Error when getting course blocks for courseId " + courseId, e);
+ }
+ }
+ }
+
+ /**
+ * Parses the course blocks structure and fill the DB
+ *
+ * @param jsonCourseBlocks
+ */
+ private static JSONObject parseCourseBlocks(JSONObject jsonCourseBlocks) {
+
+ JSONObject structuredCourse = JSONFactoryUtil.createJSONObject();
+
+ String courseId = jsonCourseBlocks.getString(EdxConstants.EDX_API_BLOCKS_ROOT);
+ JSONObject allBlocks = jsonCourseBlocks.getJSONObject(EdxConstants.EDX_API_BLOCKS_BLOCKS);
+ structuredCourse.put("courseId", courseId);
+
+ // Get sections (chapters)
+ JSONArray courseIdArray = JSONFactoryUtil.createJSONArray();
+ courseIdArray.put(courseId);
+ JSONArray courses = getChildrenBlocks(allBlocks, courseIdArray, EdxConstants.EDX_API_BLOCKS_TYPE_COURSE);
+ if (courses == null || courses.length() != 1) {
+ _log.error("Error : there is more than 1 course in the course block list");
+ return structuredCourse;
+ }
+ JSONObject course = courses.getJSONObject(0);
+ structuredCourse.put(EdxConstants.EDX_API_BLOCKS_DISPLAY_NAME,
+ course.getString(EdxConstants.EDX_API_BLOCKS_DISPLAY_NAME));
+ structuredCourse.put(EdxConstants.EDX_API_BLOCKS_STUDENT_VIEW_URL,
+ course.getString(EdxConstants.EDX_API_BLOCKS_STUDENT_VIEW_URL));
+ structuredCourse.put(EdxConstants.EDX_API_BLOCKS_LMS_WEB_URL,
+ course.getString(EdxConstants.EDX_API_BLOCKS_LMS_WEB_URL));
+ structuredCourse.put("id", course.getString(EdxConstants.EDX_API_BLOCKS_ID));
+ JSONArray sections = getChildrenBlocks(allBlocks, course.getJSONArray(EdxConstants.EDX_API_BLOCKS_CHILDREN),
+ EdxConstants.EDX_API_BLOCKS_TYPE_CHAPTER);
+
+ // Loop over sections to get sub-sections
+ for (int i = 0; i < sections.length(); i++) {
+ JSONObject section = sections.getJSONObject(i);
+ JSONArray subSections = getChildrenBlocks(allBlocks,
+ section.getJSONArray(EdxConstants.EDX_API_BLOCKS_CHILDREN),
+ EdxConstants.EDX_API_BLOCKS_TYPE_SEQUENTIAL);
+ section.put("subSections", subSections);
+
+ // Loop over subSections to get units
+ for (int j = 0; j < subSections.length(); j++) {
+ JSONObject subSection = subSections.getJSONObject(j);
+ JSONArray units = getChildrenBlocks(allBlocks,
+ subSection.getJSONArray(EdxConstants.EDX_API_BLOCKS_CHILDREN),
+ EdxConstants.EDX_API_BLOCKS_TYPE_VERTICAL);
+ subSection.put("units", units);
+
+ // Loop over units to get items
+ for (int k = 0; k < units.length(); k++) {
+ JSONObject unit = units.getJSONObject(k);
+ JSONArray items = getChildrenBlocks(allBlocks,
+ unit.getJSONArray(EdxConstants.EDX_API_BLOCKS_CHILDREN),
+ EdxConstants.EDX_API_BLOCKS_TYPE_ALL);
+ unit.put("items", items);
+ }
+ }
+ }
+ structuredCourse.put("sections", sections);
+ _log.info("le contenu de structuredCourse : " + structuredCourse.toString());
+ return structuredCourse;
+ }
+
+ /**
+ * Returns an array of JSONObjects, given their ids, among the 'allBlocks'
+ * list, with given type
+ *
+ * @param allBlocks
+ * @param childrenBlockIds
+ * @param type
+ * @return
+ */
+ private static JSONArray getChildrenBlocks(JSONObject allBlocks, JSONArray childrenBlockIds, String type) {
+
+ JSONArray result = JSONFactoryUtil.createJSONArray();
+ if (childrenBlockIds != null) {
+ // Compare blockId and type
+ for (int j = 0; j < childrenBlockIds.length(); j++) {
+
+ String childBlockId = childrenBlockIds.getString(j);
+ JSONObject block = allBlocks.getJSONObject(childBlockId);
+ if (block.getString(EdxConstants.EDX_API_BLOCKS_TYPE).equals(type)
+ || type.equals(EdxConstants.EDX_API_BLOCKS_TYPE_ALL)) {
+ result.put(block);
+ } else {
+ _log.error("Error when parsing blockId" + childBlockId + ". It has wrong type ("
+ + block.getString(EdxConstants.EDX_API_BLOCKS_TYPE) + " instead of " + type + ")");
+ }
+ }
+ }
+ _log.info("le contenu de getChildrenBlocks : " + result.toString());
+ return result;
+ }
+
+ /**
+ * Send HTTP POST request
+ *
+ * @param url
+ * @param urlParameters
+ * - the map of parameters
+ * @return
+ * @throws Exception
+ */
+ private static String sendJsonPost(String url, String params) throws Exception {
+
+ HttpClient client = new DefaultHttpClient();
+ HttpPost post = new HttpPost(url);
+
+ post.setHeader("User-Agent", USER_AGENT);
+ post.setHeader("Content-type", "application/json");
+ post.setHeader("Authorization", ACCESS_TOKEN);
+
+ post.setEntity(new ByteArrayEntity(params.getBytes("UTF8")));
+ HttpResponse response = client.execute(post);
+
+ _log.info("Sending POST request to URL : " + url);
+ _log.info("Post parameters : " + params);
+ _log.info("Response Code : " + response.getStatusLine().getStatusCode());
+
+ BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+
+ StringBuffer result = new StringBuffer();
+ String line = "";
+ while ((line = rd.readLine()) != null) {
+ result.append(line);
+ }
+
+ _log.info("POST response is " + result.toString());
+ return result.toString();
+ }
+
+ private static int sendValuePairPost(String url, List<NameValuePair> urlParameters, String response)
+ throws Exception {
+
+ HttpClient client = new DefaultHttpClient();
+ HttpPost post = new HttpPost(url);
+
+ // Add header
+ post.setHeader("User-Agent", USER_AGENT);
+ post.setHeader("Content-type", "application/x-www-form-urlencoded");
+ post.setHeader("Authorization", ACCESS_TOKEN);
+
+ post.setEntity(new UrlEncodedFormEntity(urlParameters));
+
+ HttpResponse httpResponse = client.execute(post);
+
+ // _log.info("Sending POST request to URL : " + url);
+ // _log.info("Post parameters : " + post.getEntity());
+ int statusCode = httpResponse.getStatusLine().getStatusCode();
+ // _log.info("Response Code : " + statusCode);
+
+ BufferedReader rd = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
+
+ StringBuffer result = new StringBuffer();
+ String line = "";
+ while ((line = rd.readLine()) != null) {
+ result.append(line);
+ }
+
+ // _log.info("POST response is "+result.toString());
+ response = result.toString();
+ return statusCode;
+ }
+
+ /**
+ * Send HTTP GET request
+ *
+ * @param url
+ * @param urlParameters
+ * - the map of parameters
+ * @return
+ * @throws Exception
+ */
+ private static String sendGet(String url) throws Exception {
+
+ URL obj = new URL(url);
+ HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
+
+ // add request header
+ con.setRequestMethod("GET");
+ con.setRequestProperty("User-Agent", USER_AGENT);
+ con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
+ con.setRequestProperty("Authorization", ACCESS_TOKEN);
+ con.setDoOutput(true);
+
+ _log.info("Sending GET request to URL : " + url);
+ int responseCode = con.getResponseCode();
+ _log.info("Response Code : " + responseCode);
+ if (responseCode != HTTP_CODE_OK) {
+ return "";
+ }
+
+ // Read response
+ BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ String inputLine;
+ StringBuffer getResponse = new StringBuffer();
+ while ((inputLine = in.readLine()) != null) {
+ getResponse.append(inputLine);
+ }
+ in.close();
+
+ return getResponse.toString();
+ }
+
+ /**
+ * Builds the username in edx, following some constraints
+ *
+ * @param user
+ * @return
+ */
+ private static String buildUserName(User user) {
+
+ String result = user.getScreenName();
+
+ // No space
+ result = result.replaceAll(" ", "_");
+
+ // Remove special characters
+ result = Normalizer.normalize(result, Normalizer.Form.NFD);
+ result = result.replaceAll("[\u0300-\u036F]", "");
+
+ // a-z,A-Z,0-9 characters only
+ StringBuilder str = new StringBuilder();
+ for (char c : result.toCharArray()) {
+ if (Character.isLetterOrDigit(c) || c == '_') {
+ str.append(c);
+ }
+ }
+ result = str.toString();
+
+ // Limit to 30 char
+ if (result.length() > MAX_USERNAME_LENGTH) {
+ result = result.substring(0, MAX_USERNAME_LENGTH - 1);
+ }
+ return result;
+ }
+}