Java tutorial
/** * Copyright 2009 Welocalize, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. * * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * */ package com.globalsight.webservices; import java.rmi.RemoteException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.Vector; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.jboss.util.Strings; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.globalsight.cxe.entity.fileextension.FileExtensionImpl; import com.globalsight.cxe.entity.fileprofile.FileProfile; import com.globalsight.cxe.entity.fileprofile.FileProfileImpl; import com.globalsight.cxe.persistence.fileprofile.FileProfilePersistenceManager; import com.globalsight.diplomat.util.database.ConnectionPool; import com.globalsight.diplomat.util.database.ConnectionPoolException; import com.globalsight.everest.company.Company; import com.globalsight.everest.company.CompanyWrapper; import com.globalsight.everest.foundation.BasicL10nProfile; import com.globalsight.everest.foundation.LocalePair; import com.globalsight.everest.foundation.User; import com.globalsight.everest.foundation.UserRoleImpl; import com.globalsight.everest.jobhandler.Job; import com.globalsight.everest.page.PageWordCounts; import com.globalsight.everest.page.SourcePage; import com.globalsight.everest.page.TargetPage; import com.globalsight.everest.page.pageexport.ExportBatchEvent; import com.globalsight.everest.page.pageexport.ExportParameters; import com.globalsight.everest.permission.Permission; import com.globalsight.everest.persistence.tuv.SegmentTuvUtil; import com.globalsight.everest.projecthandler.MachineTranslationProfile; import com.globalsight.everest.projecthandler.Project; import com.globalsight.everest.projecthandler.ProjectImpl; import com.globalsight.everest.projecthandler.ProjectInfo; import com.globalsight.everest.projecthandler.TranslationMemoryProfile; import com.globalsight.everest.projecthandler.WfTemplateSearchParameters; import com.globalsight.everest.projecthandler.WorkflowTemplateInfo; import com.globalsight.everest.servlet.util.ServerProxy; import com.globalsight.everest.taskmanager.Task; import com.globalsight.everest.taskmanager.TaskImpl; import com.globalsight.everest.taskmanager.TaskManager; import com.globalsight.everest.usermgr.UserManagerException; import com.globalsight.everest.webapp.pagehandler.PageHandler; import com.globalsight.everest.webapp.pagehandler.administration.mtprofile.MTProfileHandlerHelper; import com.globalsight.everest.webapp.pagehandler.administration.users.UserUtil; import com.globalsight.everest.webapp.pagehandler.administration.workflow.WorkflowTemplateHandlerHelper; import com.globalsight.everest.webapp.pagehandler.tasks.TaskHelper; import com.globalsight.everest.workflow.ConditionNodeTargetInfo; import com.globalsight.everest.workflow.WorkflowArrow; import com.globalsight.everest.workflow.WorkflowConstants; import com.globalsight.everest.workflow.WorkflowOwners; import com.globalsight.everest.workflow.WorkflowTask; import com.globalsight.everest.workflow.WorkflowTaskInstance; import com.globalsight.everest.workflow.WorkflowTemplate; import com.globalsight.everest.workflowmanager.Workflow; import com.globalsight.everest.workflowmanager.WorkflowImpl; import com.globalsight.ling.common.URLEncoder; import com.globalsight.persistence.hibernate.HibernateUtil; import com.globalsight.util.Assert; import com.globalsight.util.GeneralException; import com.globalsight.util.GlobalSightLocale; import com.globalsight.util.StringUtil; import com.globalsight.util.edit.EditUtil; import com.globalsight.webservices.vo.JobFiles; /** * WebService APIs of GlobalSight handles web services related to projects, * jobs, workflows, import, export,setup, etc. for GlobalSight * * NOTE: The web service that Apache Axis generates will be named * Ambassador4Falcon */ public class Ambassador4Falcon extends JsonTypeWebService { // Method names private static final Logger logger = Logger.getLogger(Ambassador4Falcon.class); public static final String GET_TRANSLATION_PERCENTAGE = "getTranslationPercentage"; public static final String GET_JOB_IDS_WITH_STATUS_CHANGED = "getJobIDsWithStatusChanged"; public static final String GET_DETAILED_WORD_COUNTS = "getDetailedWordcounts"; public static final String GET_WORKFLOW_TEMPLATE_NAMES = "getWorkflowTemplateNames"; public static final String GET_WORKFLOW_TEMPLATE_INFO = "getWorkflowTemplateInfo"; public static final String MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES = "modifyWorkflowTemplateAssignees"; public static final String GET_WORK_OFFLINE_FILES = "getWorkOfflineFiles"; public static final String UPLOAD_WORK_OFFLINE_FILES = "uploadWorkOfflineFiles"; public static final String IMPORT_WORK_OFFLINE_FILES = "importWorkOfflineFiles"; public static final String ACCEPT_TASK = "acceptTask"; public static final String COMPLETE_TASK = "completeTask"; public static final String REJECT_TASK = "rejectTask"; public static final String EXPORT_JOB = "exportJob"; public static final String EXPORT_WORKFLOW = "exportWorkflow"; public static final String GET_JOB_EXPORT_FILES = "getJobExportFiles"; public static final String GET_JOB_EXPORT_WORKFLOW_FILES = "getJobExportWorkflowFiles"; public static final String GET_IN_CONTEXT_REVIEW_LINK = "getInContextReviewLink"; public static final String GET_ALL_PROJECT_PROFILES = "getAllProjectProfiles"; public static final String GET_ALL_PROJECTS_BY_USER = "getAllProjectsByUser"; public static final String GET_ACTIVITY_LIST = "getActivityList"; private static String NOT_IN_DB = "This job is not ready for query: "; private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * Constructs a GlobalSight WebService object. */ public Ambassador4Falcon() { logger.info("Creating new GlobalSight Web Service for Falcon."); } /** * Return job IDs that "changes" have happened in specified past interval * minutes. This includes general events such as job creation, workflow * dispatch, workflow completion, task acceptance, task completion etc. * * @param p_accessToken * -- login user's token * @param p_intervalInMinute * -- interval time in minutes. * @param p_companyName * --get job id of the company * @return jobIDs in json string. A sample result is like: * {"JOB_ID":"204,213,215,216,218,220,190,202,205,217,219"} * @throws WebServiceException * */ public String getJobIDsWithStatusChanged(String p_accessToken, int p_intervalInMinute, String p_companyName) throws WebServiceException { checkAccess(p_accessToken, GET_JOB_IDS_WITH_STATUS_CHANGED); String jobsView = checkPermissionReturnStr(p_accessToken, Permission.JOBS_VIEW); if (StringUtil.isNotEmpty(jobsView)) return jobsView; String json = ""; WebServicesLog.Start activityStart = null; Connection connection = null; PreparedStatement query = null; ResultSet results = null; try { String userName = getUsernameFromSession(p_accessToken); Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", userName); activityArgs.put("intervalInMinute", p_intervalInMinute); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "getJobIDsWithStatusChanged(p_accessToken,p_intervalInMinute)", activityArgs); if (StringUtil.isEmpty(p_accessToken) || p_intervalInMinute < 1) { return makeErrorJson(GET_JOB_IDS_WITH_STATUS_CHANGED, "Invaild time range parameter."); } if (StringUtil.isEmpty(p_companyName)) { return makeErrorJson(GET_JOB_IDS_WITH_STATUS_CHANGED, "Invaild comoany name parameter."); } // int hours = getHours(p_sinceTime); Calendar calendar = Calendar.getInstance(); // calendar.add(Calendar.HOUR, 0 - hours); calendar.add(Calendar.MINUTE, 0 - p_intervalInMinute); String timeStamp = dateFormat.format(calendar.getTime()); User user = getUser(getUsernameFromSession(p_accessToken)); String curCompanyName = user.getCompanyName(); String curCompanyId = CompanyWrapper.getCompanyIdByName(curCompanyName); if (!curCompanyId.equals("1") && !curCompanyName.equalsIgnoreCase(p_companyName)) { return makeErrorJson(GET_JOB_IDS_WITH_STATUS_CHANGED, "Invaild comoany name parameter."); } String sql = "SELECT DISTINCT workflow.JOB_ID FROM task_info, workflow, job " + "WHERE workflow.COMPANY_ID = ? " + "AND (task_info.ACCEPTED_DATE > ? " + " OR task_info.COMPLETED_DATE > ? " + " OR job.TIMESTAMP > ? " + " OR workflow.TIMESTAMP > ? " + " OR workflow.COMPLETED_DATE > ?" + " OR workflow.DISPATCH_DATE > ?) " + "AND workflow.IFLOW_INSTANCE_ID = task_info.WORKFLOW_ID " + "AND job.ID = workflow.JOB_ID"; connection = ConnectionPool.getConnection(); query = connection.prepareStatement(sql); query.setString(1, CompanyWrapper.getCompanyIdByName(p_companyName)); query.setString(2, timeStamp); query.setString(3, timeStamp); query.setString(4, timeStamp); query.setString(5, timeStamp); query.setString(6, timeStamp); query.setString(7, timeStamp); results = query.executeQuery(); json = resultSetToJson("JOB_ID", results); } catch (Exception e) { return makeErrorJson(GET_JOB_IDS_WITH_STATUS_CHANGED, "Cannot get jobs correctly. " + e.getMessage()); } finally { if (activityStart != null) { activityStart.end(); } releaseDBResource(results, query, connection); } return json; } /** * Get translation percentage of specified task and its target pages. * * @param p_accessToken * -- login user's token * @param p_taskId * -- task ID in string, example: "8389" * @return String in JSON style, an example is: * {"jobId":452, "jobName":"3536_001_166227234", "taskId":8389, "taskName":"Translation1_1007", "targetLocale":"German (Germany) [de_DE]", "sourceLocale":"English (United States) [en_US]", "taskTranslationPrecentage":78, * "targetPages":"[{\"targetPageName\":\"en_US\\\\452\\\\Internet Explorer.docx\",\"pageTranslationPrecentage\":70},{\"targetPageName\":\"en_US\\\\452\\\\Internet Explorer2.docx\",\"pageTranslationPrecentage\":90}]"} */ public String getTranslationPercentage(String p_accessToken, String p_taskId) throws WebServiceException { checkAccess(p_accessToken, GET_TRANSLATION_PERCENTAGE); WebServicesLog.Start activityStart = null; Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("taskId", p_taskId); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "getTranslationPercentage(accessToken, p_taskId)", activityArgs); User curUser = getUser(getUsernameFromSession(p_accessToken)); Task task = TaskHelper.getTask(Long.parseLong(p_taskId)); JSONObject jsonObj = new JSONObject(); try { if (task != null) { long companyId = getCompanyByName(curUser.getCompanyName()).getId(); if (companyId != 1 && task.getCompanyId() != companyId) { return makeErrorJson(GET_TRANSLATION_PERCENTAGE, "Logged user is not super user or the task does not belong to the company of logger user."); } jsonObj.put("jobId", task.getJobId()); jsonObj.put("jobName", task.getJobName()); jsonObj.put("sourceLocale", task.getSourceLocale().getDisplayName()); jsonObj.put("targetLocale", task.getTargetLocale().getDisplayName()); jsonObj.put("taskId", task.getId()); jsonObj.put("taskName", task.getTaskName()); int taskPrecentage = SegmentTuvUtil.getTranslatedPercentageForTask(task); jsonObj.put("taskTranslationPrecentage", taskPrecentage); JSONArray array = new JSONArray(); List list = task.getTargetPages(); for (int i = 0; i < list.size(); i++) { JSONObject json = new JSONObject(); TargetPage targetPage = (TargetPage) list.get(i); json.put("targetPageName", targetPage.getExternalPageId()); int pagePercentage = SegmentTuvUtil.getTranslatedPercentageForTargetPage(targetPage.getId()); json.put("pageTranslationPrecentage", pagePercentage); array.put(json); } jsonObj.put("targetPages", array.toString()); } } catch (Exception e) { e.printStackTrace(); } if (activityStart != null) { activityStart.end(); } return jsonObj.toString(); } /** * <p> * Return job ID, jobName, description, creationDate, lang, Matches, 95-99%, * 85-94%, 75-84%, noMatch, repetitions, inContextMatches, MT, total, * MTConfidenceScore, filePath, fileName for specified jobs. This is similar * with "Detailed Word Counts By Job" report. * </p> * <p> * Falcon connector will use this API to read and price MT'd words, so it * can quote MT projects. Currently, the Falcon connector assumes for MT * projects all new words are MT'd words. * </p> * * @param p_accessToken * -- login user's token * @param p_jobIds * -- jobIds in array. * @param includeMTData * -- flag to decide if include MT'd word counts. * @return String in JSON. A sample is like: * [{"total":236,"85-94%":0,"jobId":39,"filePath":"en_US\\39\\global","MTConfidenceScore":100,"inContextMatches":0,"75-84%":0,"95-99%":0,"jobName":"mumt_22759766","lang":"fr_FR","MT":0,"repetitions":0, * "noMatch":0,"projectDescription":"com1","creationDate ":"2013-11-01 11:48:20","fileName":"Welocalize_Company.html","100%Matches":236}, * {"total":236,"85-94%":0,"jobId":39,"filePath":"en_US\\39\\global","MTConfidenceScore":100,"inContextMatches":0,"75-84%":0,"95-99%":0,"jobName":"mumt_22759766","lang":"de_DE","MT":0,"repetitions":0, * "noMatch":236,"projectDescription":"com1","creationDate ":"2013-11-01 11:48:20","fileName":"Welocalize_Company.html","100%Matches":0}, * {"total":236,"85-94%":13,"jobId":38,"filePath":"en_US\\38\\global","MTConfidenceScore":100,"inContextMatches":53,"75-84%":13,"95-99%":30,"jobName":"mty_826004265","lang":"fr_FR","MT":0,"repetitions":0, * "noMatch":52,"projectDescription":"Template","creationDate ":"2013-11-01 11:41:14","fileName":"Welocalize_Company.html","100%Matches":75}] * * @throws WebServiceException * */ public String getDetailedWordcounts(String p_accessToken, String[] p_jobIds, Boolean p_includeMTData) throws WebServiceException { checkAccess(p_accessToken, GET_DETAILED_WORD_COUNTS); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.REPORTS_DELL_FILE_LIST); if (StringUtil.isNotEmpty(returnStr)) return returnStr; String json = ""; WebServicesLog.Start activityStart = null; try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("jobIds", p_jobIds); activityArgs.put("includeMTData", p_includeMTData); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "getDetailedWordcounts(accessToken, jobIds, includeMTData)", activityArgs); if (StringUtil.isEmpty(p_accessToken) || p_jobIds.length < 1) { return makeErrorJson(GET_DETAILED_WORD_COUNTS, "Invaild jobIds parameter."); } User curUser = getUser(getUsernameFromSession(p_accessToken)); Company company = getCompanyByName(curUser.getCompanyName()); JSONArray array = new JSONArray(); for (String jobIdstr : p_jobIds) { if (!StringUtils.isNumeric(jobIdstr)) continue; long jobId = Long.valueOf(jobIdstr); Job job = ServerProxy.getJobHandler().getJobById(jobId); if (job != null) { // If job is not from current user's company, ignore. if (company.getId() != 1 && company.getId() != job.getCompanyId()) { continue; } int threshold = job.getLeverageMatchThreshold(); String jobname = job.getJobName(); String pDesc = getProjectDesc(job); String createDate = dateFormat.format(job.getCreateDate()); for (Workflow p_workflow : job.getWorkflows()) { int mtConfidenceScore = p_workflow.getMtConfidenceScore(); String lang = p_workflow.getTargetLocale().toString(); for (TargetPage tg : p_workflow.getTargetPages()) { JSONObject jsonObj = new JSONObject(); jsonObj.put("jobId", jobId); jsonObj.put("jobName", jobname); setFilePathName(tg, jsonObj); jsonObj.put("projectDescription", pDesc); jsonObj.put("creationDate", createDate); jsonObj.put("lang", lang); try { addWordCountForJson(tg, jsonObj, threshold, mtConfidenceScore, p_includeMTData); } catch (Exception e) { e.printStackTrace(); } array.put(jsonObj); } } } } json = array.toString(); } catch (Exception e) { return makeErrorJson(GET_DETAILED_WORD_COUNTS, "Cannot get Wordcounts correctly. " + e.getMessage()); } finally { if (activityStart != null) { activityStart.end(); } } return json; } /** * Accept specified task. * * @param p_accessToken * The access token received from the login. * @param p_taskId * Task Id to be accepted. * @return String in JSON. A sample is like: * {"acceptTask":"success"} * @throws WebServiceException */ public String acceptTask(String p_accessToken, String p_taskId) throws WebServiceException { String rtnString = "success"; checkAccess(p_accessToken, ACCEPT_TASK); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.ACTIVITIES_ACCEPT); if (StringUtil.isNotEmpty(returnStr)) return returnStr; try { Assert.assertNotEmpty(p_accessToken, "Access token"); Assert.assertIsInteger(p_taskId); } catch (Exception e) { logger.error(e.getMessage(), e); return makeErrorJson(ACCEPT_TASK, e.getMessage()); } String acceptorName = getUsernameFromSession(p_accessToken); String acceptor = UserUtil.getUserIdByName(acceptorName); Task task = null; try { task = TaskHelper.getTask(Long.parseLong(p_taskId)); } catch (Exception e) { logger.error(e.getMessage(), e); String message = "Failed to get task object by taskId : " + p_taskId; return makeErrorJson(ACCEPT_TASK, message); } WebServicesLog.Start activityStart = null; try { if (task != null) { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", acceptorName); activityArgs.put("taskId", p_taskId); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "acceptTask(p_accessToken,p_taskId)", activityArgs); if (task.getState() == Task.STATE_ACCEPTED || task.getState() == Task.STATE_COMPLETED) { return makeErrorJson(ACCEPT_TASK, "The current task has been accepted or completed state."); } WorkflowTaskInstance wfTask = ServerProxy.getWorkflowServer().getWorkflowTaskInstance(acceptor, task.getId(), WorkflowConstants.TASK_ALL_STATES); task.setWorkflowTask(wfTask); List allAssignees = task.getAllAssignees(); if (allAssignees != null && allAssignees.size() > 0) { if (!allAssignees.contains(acceptor)) { String message = "'" + acceptor + "' is not an available assignee for current task " + p_taskId; logger.warn(message); return makeErrorJson(ACCEPT_TASK, message); } } // GS will check if the acceptor is PM or available users TaskHelper.acceptTask(acceptor, task); } else { return makeErrorJson(ACCEPT_TASK, "Invaild task id."); } } catch (Exception e) { logger.error(e.getMessage(), e); String message = "Failed to accept task for taskId : " + p_taskId + ",maybe '" + acceptor + "' do not have the authority to operate the task"; return makeErrorJson(ACCEPT_TASK, message); } finally { if (activityStart != null) { activityStart.end(); } } return rtnString; } /** * Complete task * * @param p_accessToken * The access token received from the login. * @param p_taskId * Task Id to be completed. * @param p_destinationArrow * This points to the next activity. Null if this task has no * condition node. * @return String in JSON. A sample is like: * {"completeTask":"success"} * @throws WebServiceException */ public String completeTask(String p_accessToken, String p_taskId, String p_destinationArrow) throws WebServiceException { String rtnStr = "success"; checkAccess(p_accessToken, "completeTask"); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.ACTIVITIES_ACCEPT); if (StringUtil.isNotEmpty(returnStr)) return returnStr; try { Assert.assertNotEmpty(p_accessToken, "Access token"); Assert.assertIsInteger(p_taskId); } catch (Exception e) { logger.error(e.getMessage(), e); return makeErrorJson(COMPLETE_TASK, e.getMessage()); } String userName = this.getUsernameFromSession(p_accessToken); String userId = UserUtil.getUserIdByName(userName); // Task object TaskManager taskManager = ServerProxy.getTaskManager(); Task task = null; try { task = taskManager.getTask(Long.parseLong(p_taskId)); if (task == null) return makeErrorJson(COMPLETE_TASK, "Invaild task id."); } catch (RemoteException re) { String msg = "Fail to get task object by taskId : " + p_taskId; logger.error(msg, re); return makeErrorJson(COMPLETE_TASK, msg); } catch (Exception ex) { logger.error(ex.getMessage(), ex); } // Compelte task WebServicesLog.Start activityStart = null; try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", userName); activityArgs.put("taskId", p_taskId); activityArgs.put("destinationArrow", p_destinationArrow); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "completeTask(p_accessToken,p_taskId,p_destinationArrow)", activityArgs); // Find the user to complete task. WorkflowTaskInstance wfTask = ServerProxy.getWorkflowServer().getWorkflowTaskInstance(userId, task.getId(), WorkflowConstants.TASK_ALL_STATES); task.setWorkflowTask(wfTask); List allAssignees = task.getAllAssignees(); if (allAssignees != null && allAssignees.size() > 0) { if (!allAssignees.contains(userId)) { String message = "'" + userName + "' is not an available assignee for current task " + p_taskId; logger.warn(message); return makeErrorJson(COMPLETE_TASK, message); } } Vector conditionNodes = wfTask.getConditionNodeTargetInfos(); if (conditionNodes != null && conditionNodes.size() > 0) { HashSet<String> arrowNames = new HashSet<String>(); for (int i = 0; i < conditionNodes.size(); i++) { ConditionNodeTargetInfo info = (ConditionNodeTargetInfo) conditionNodes.get(i); arrowNames.add(info.getArrowName()); } if (!arrowNames.contains(p_destinationArrow)) { String message = "\"" + p_destinationArrow + "\" is not a valid outgoing arrow name."; logger.warn(message); return makeErrorJson(COMPLETE_TASK, message); } } TaskImpl dbTask = HibernateUtil.get(TaskImpl.class, task.getId()); ProjectImpl project = (ProjectImpl) dbTask.getWorkflow().getJob().getProject(); WorkflowImpl workflowImpl = (WorkflowImpl) dbTask.getWorkflow(); boolean isCheckUnTranslatedSegments = project.isCheckUnTranslatedSegments(); boolean isRequriedScore = workflowImpl.getScorecardShowType() == 1 ? true : false; boolean isReviewOnly = dbTask.isReviewOnly(); if (isCheckUnTranslatedSegments && !isReviewOnly) { int percentage = SegmentTuvUtil.getTranslatedPercentageForTask(task); if (100 != percentage) { rtnStr = "The task is not 100% translated and can not be completed."; return makeErrorJson(COMPLETE_TASK, rtnStr); } } if (isRequriedScore && isReviewOnly) { if (StringUtil.isEmpty(workflowImpl.getScorecardComment())) { rtnStr = "The task is not scored and can not be completed."; return makeErrorJson(COMPLETE_TASK, rtnStr); } } if (task.getState() == Task.STATE_ACCEPTED) { ServerProxy.getTaskManager().completeTask(userId, task, p_destinationArrow, null); } else { rtnStr = "Cannot complete this task as it is not in 'ACCEPTED' state"; return makeErrorJson(COMPLETE_TASK, rtnStr); } } catch (Exception ex) { String msg = "Fail to complete task : " + p_taskId + " ; " + ex.getMessage(); logger.error(msg, ex); return makeErrorJson(COMPLETE_TASK, msg); } finally { if (activityStart != null) { activityStart.end(); } } return rtnStr; } /** * Reject specified task. * * @param p_accessToken * The access token received from the login. * * @param p_taskId * Task Id to be accepted. * * @param p_rejectComment * Reject comment. * @return String in JSON. A sample is like: * {"rejectTask":"success"} * @throws WebServiceException */ public String rejectTask(String p_accessToken, String p_taskId, String p_rejectComment) throws WebServiceException { String rtnStr = "success"; checkAccess(p_accessToken, REJECT_TASK); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.ACTIVITIES_REJECT_AFTER_ACCEPTING); if (StringUtil.isNotEmpty(returnStr)) return returnStr; try { Assert.assertNotEmpty(p_accessToken, "Access token"); Assert.assertIsInteger(p_taskId); Assert.assertNotEmpty(p_rejectComment, "Reject comment"); } catch (Exception e) { logger.error(e.getMessage(), e); return makeErrorJson(REJECT_TASK, e.getMessage()); } // rejector String rejectUserName = getUsernameFromSession(p_accessToken); String rejectUserId = UserUtil.getUserIdByName(rejectUserName); Task task = null; WebServicesLog.Start activityStart = null; try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", rejectUserName); activityArgs.put("p_taskId", p_taskId); activityArgs.put("p_rejectComment", p_rejectComment); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "rejectTask(p_accessToken,p_taskId,p_rejectComment)", activityArgs); WorkflowTaskInstance wfTask = ServerProxy.getWorkflowServer().getWorkflowTaskInstance(rejectUserId, Long.parseLong(p_taskId), WorkflowConstants.TASK_ALL_STATES); task = (Task) HibernateUtil.get(TaskImpl.class, Long.parseLong(p_taskId)); task.setWorkflowTask(wfTask); String rejectComment = EditUtil.utf8ToUnicode(p_rejectComment); if (task.getState() == Task.STATE_ACTIVE || task.getState() == Task.STATE_ACCEPTED) { TaskHelper.rejectTask(rejectUserId, task, rejectComment); } } catch (Exception e) { logger.error(e.getMessage(), e); String message = "Failed to reject task by taskId : " + p_taskId; return makeErrorJson(REJECT_TASK, message); } finally { if (activityStart != null) { activityStart.end(); } } return rtnStr; } /** * Get all projects relevant information for specified company name. * * @param p_accessToken * -- login user's token * @param p_companyName * -- company name to get data from * @return JSON string, sample is * "[{"projectID":1037,"projectManager":"gsalliepm","projectName":"Template","l10n_profiles":[{"sourceLocale":"English (United States) [en_US]" , "fileProfiles":[{"sourceFileFormat":"XML","fileProfileName": "file_profile_xml_02","fileProfileId":4,"fileExtensions":"xml"}],"tmProfileId":1, * "workflows":[{"wfTemplateLocalePair": "English (United States) [en_US] -> German (Germany) [de_DE]","mtProfileId":4,"wfTemplateName":"en_de_template","mtProfileEngine":"MS_Translator","mtProfileConfidenceScore":"90%","mtProfileName":"859MT_1_import_1","wfTemplateId":1313}, * {"wfTemplateLocalePair":"English (United States) [en_US] -> French (France) [fr_FR]" ,"mtProfileId":3,"wfTemplateName":"en_fr_template","mtProfileEngine":"MS_Translator","mtProfileConfidenceScore":"90%","mtProfileName" :"859MT_1","wfTemplateId":1312}, * {"wfTemplateLocalePair":"English (United States) [en_US] -> Spanish (Spain) [es_ES]" ,"mtProfileId":5,"wfTemplateName":"en_es_template","mtProfileEngine":"MS_Translator","mtProfileConfidenceScore":"90%","mtProfileName":"859MT_1_import_2","wfTemplateId":1314}], * "priority":3,"workflowDispatchType":"Automatic","l10nProfileId":12,"tmProfileName":"tm_profile_01","l10nProfileName":"localization_profile_en_01"}]}]". * @throws WebServiceException */ public String getAllProjectProfiles(String p_accessToken, String p_companyName) throws WebServiceException { checkAccess(p_accessToken, GET_ALL_PROJECT_PROFILES); if (StringUtil.isEmpty(p_companyName)) { return makeErrorJson(GET_ALL_PROJECT_PROFILES, "Invaild company name"); } String companyId = null; try { companyId = CompanyWrapper.getCompanyIdByName(p_companyName); } catch (Exception e) { return makeErrorJson(GET_ALL_PROJECT_PROFILES, "No company named with '" + p_companyName + "'."); } String curUserName = getUsernameFromSession(p_accessToken); User curUser = UserUtil.getUserById(UserUtil.getUserIdByName(curUserName)); String curCompanyName = curUser.getCompanyName(); String curCompanyId = CompanyWrapper.getCompanyIdByName(curCompanyName); if (!curCompanyId.equals("1") && !curCompanyName.equalsIgnoreCase(p_companyName)) { return makeErrorJson(GET_ALL_PROJECT_PROFILES, "Current user is neither super user nor user from company '" + p_companyName + "'."); } List<Project> projectList = null; WebServicesLog.Start activityStart = null; JSONArray projectArray = new JSONArray(); try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", curUserName); activityArgs.put("p_companyName", p_companyName); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "getAllProjectProfiles(p_accessToken,p_companyName)", activityArgs); projectList = ServerProxy.getProjectHandler().getProjectsByCompanyId(Long.parseLong(companyId)); for (Project project : projectList) { JSONObject projectJson = new JSONObject(); projectJson.put("projectID", project.getId()); projectJson.put("projectName", project.getName()); projectJson.put("projectManager", project.getProjectManager()); if (project.getAttributeSet() != null) { projectJson.put("attributeGroupId", project.getAttributeSet().getId()); projectJson.put("attributeGroupName", project.getAttributeSet().getName()); } JSONArray l10ProfileArray = new JSONArray(); Collection allL10Profiles = ServerProxy.getProjectHandler() .getL10ProfilesByProjectId(project.getId()); Iterator it = allL10Profiles.iterator(); while (it.hasNext()) { JSONObject l10Json = new JSONObject(); BasicL10nProfile l10 = (BasicL10nProfile) it.next(); l10Json.put("l10nProfileId", l10.getId()); l10Json.put("l10nProfileName", l10.getName()); l10Json.put("sourceLocale", l10.getSourceLocale().getDisplayName()); if (l10.isAutoDispatch()) { l10Json.put("workflowDispatchType", "Automatic"); } else { l10Json.put("workflowDispatchType", "Manual"); } l10Json.put("priority", l10.getPriority()); // tmProfile Iterator itTm = l10.getTmProfiles().iterator(); while (itTm.hasNext()) { TranslationMemoryProfile tmProfile = (TranslationMemoryProfile) itTm.next(); l10Json.put("tmProfileId", tmProfile.getId()); l10Json.put("tmProfileName", tmProfile.getName()); } // work flow JSONArray workflowArray = new JSONArray(); GlobalSightLocale[] targets = l10.getTargetLocales(); for (int i = 0; i < targets.length; i++) { JSONObject workflowJson = new JSONObject(); WorkflowTemplateInfo workflowTemplateInfo = (WorkflowTemplateInfo) l10 .getWorkflowTemplateInfo((GlobalSightLocale) targets[i]); workflowJson.put("wfTemplateId", workflowTemplateInfo.getId()); workflowJson.put("wfTemplateName", workflowTemplateInfo.getName()); LocalePair lp = ServerProxy.getLocaleManager().getLocalePairBySourceTargetIds( workflowTemplateInfo.getSourceLocale().getId(), workflowTemplateInfo.getTargetLocale().getId()); String localePair = lp.getSource().getDisplayName() + " -> " + lp.getTarget().getDisplayName(); workflowJson.put("wfTemplateLocalePair", localePair); MachineTranslationProfile mt = MTProfileHandlerHelper.getMTProfileByRelation(l10.getId(), workflowTemplateInfo.getId()); if (mt != null) { workflowJson.put("mtProfileId", mt.getId()); workflowJson.put("mtProfileName", mt.getMtProfileName()); workflowJson.put("mtProfileEngine", mt.getMtEngine()); workflowJson.put("mtProfileConfidenceScore", mt.getMtConfidenceScore() + "%"); } workflowArray.put(workflowJson); } l10Json.put("workflows", workflowArray); // fileProfile JSONArray fileProfileArray = new JSONArray(); Iterator itFileProfile = l10.getFileProfiles().iterator(); while (itFileProfile.hasNext()) { JSONObject fileProfileJson = new JSONObject(); FileProfileImpl fileProfile = (FileProfileImpl) itFileProfile.next(); if (!fileProfile.isActive()) continue; fileProfileJson.put("fileProfileId", fileProfile.getId()); fileProfileJson.put("fileProfileName", fileProfile.getName()); fileProfileJson.put("sourceFileFormat", ServerProxy.getFileProfilePersistenceManager() .getKnownFormatTypeById(fileProfile.getKnownFormatTypeId(), false).getName()); Vector<Long> extensionIds = fileProfile.getFileExtensionIds(); if (extensionIds.size() == 0) { fileProfileJson.put("fileExtensions", "All"); } else { String fileExtensions = ""; for (int j = 0; j < extensionIds.size(); j++) { FileExtensionImpl extension = HibernateUtil.get(FileExtensionImpl.class, extensionIds.get(j)); fileExtensions += extension.getName() + ","; } if (fileExtensions != "" && fileExtensions.endsWith(",")) { fileProfileJson.put("fileExtensions", fileExtensions.substring(0, fileExtensions.lastIndexOf(","))); } } fileProfileArray.put(fileProfileJson); } l10Json.put("fileProfiles", fileProfileArray); l10ProfileArray.put(l10Json); } projectJson.put("l10n_profiles", l10ProfileArray); projectArray.put(projectJson); } } catch (Exception e) { String message = "Unable to get all projects"; logger.error(e.getMessage(), e); message = makeErrorJson(GET_ALL_PROJECT_PROFILES, message); throw new WebServiceException(message); } finally { if (activityStart != null) { activityStart.end(); } } return projectArray.toString(); } private int addWordCountForJson(TargetPage tg, JSONObject jsonObj, int threshold, int mtConfidenceScore, boolean includeMTData) throws Exception { boolean isInContextMatch = PageHandler.isInContextMatch(tg.getSourcePage().getRequest().getJob()); PageWordCounts pageWC = tg.getWordCount(); // 100% match int _100MatchWordCount = 0; // in context word match int inContextWordCount = 0; // Context match int contextMatchWC = pageWC.getContextMatchWordCount(); if (isInContextMatch) { inContextWordCount = pageWC.getInContextWordCount(); _100MatchWordCount = pageWC.getSegmentTmWordCount(); contextMatchWC = 0; } else { _100MatchWordCount = pageWC.getTotalExactMatchWordCount(); contextMatchWC = 0; } int hiFuzzyWordCount = pageWC.getThresholdHiFuzzyWordCount(); int medHiFuzzyWordCount = pageWC.getThresholdMedHiFuzzyWordCount(); int medFuzzyWordCount = pageWC.getThresholdMedFuzzyWordCount(); int lowFuzzyWordCount = pageWC.getThresholdLowFuzzyWordCount(); int noMatchWordCount = pageWC.getThresholdNoMatchWordCount(); int repetitionsWordCount = pageWC.getRepetitionWordCount(); int totalWords = pageWC.getTotalWordCount(); // MT int mtTotalWordCount = pageWC.getMtTotalWordCount(); int mtExactMatchWordCount = pageWC.getMtExactMatchWordCount(); int mtFuzzyNoMatchWordCount = pageWC.getMtFuzzyNoMatchWordCount(); int mtRepetitionsWordCount = pageWC.getMtRepetitionsWordCount(); int noMatchWorcCountForDisplay = lowFuzzyWordCount + noMatchWordCount; // If include MT column, need adjust word count according to threshold // and MT confidence score. if (includeMTData) { if (mtConfidenceScore == 100) { _100MatchWordCount = _100MatchWordCount - mtExactMatchWordCount; } else if (mtConfidenceScore < 100 && mtConfidenceScore >= threshold) { if (mtConfidenceScore >= 95) { hiFuzzyWordCount -= mtFuzzyNoMatchWordCount; } else if (mtConfidenceScore < 95 && mtConfidenceScore >= 85) { medHiFuzzyWordCount -= mtFuzzyNoMatchWordCount; } else if (mtConfidenceScore < 85 && mtConfidenceScore >= 75) { medFuzzyWordCount -= mtFuzzyNoMatchWordCount; } else if (mtConfidenceScore < 75) { noMatchWorcCountForDisplay -= mtFuzzyNoMatchWordCount; } repetitionsWordCount -= mtRepetitionsWordCount; } else if (mtConfidenceScore < threshold) { noMatchWorcCountForDisplay -= mtFuzzyNoMatchWordCount; repetitionsWordCount -= mtRepetitionsWordCount; } } // write the information of word count jsonObj.put("100%Matches", _100MatchWordCount); jsonObj.put("95-99%", hiFuzzyWordCount); jsonObj.put("85-94%", medHiFuzzyWordCount); jsonObj.put("75-84%", medFuzzyWordCount); jsonObj.put("noMatch", noMatchWorcCountForDisplay); jsonObj.put("repetitions", repetitionsWordCount); if (isInContextMatch) { jsonObj.put("inContextMatches", inContextWordCount); } else { // We use the same key to avoid user's confusion. jsonObj.put("inContextMatches", contextMatchWC); } if (includeMTData) { jsonObj.put("MT", mtTotalWordCount); } jsonObj.put("total", totalWords); if (includeMTData) { jsonObj.put("MTConfidenceScore", mtConfidenceScore); } return totalWords; } private String getProjectDesc(Job p_job) { Project p = p_job.getL10nProfile().getProject(); String d = StringUtils.chomp(p.getDescription()); String desc = null; if (d == null || d.length() == 0) desc = p.getName(); else desc = p.getName() + "-" + d; return desc; } private void setFilePathName(TargetPage tg, JSONObject jsonObj) throws Exception { String fileFullName = tg.getSourcePage().getExternalPageId(); String filePath = fileFullName; String fileName = " "; if (fileFullName.indexOf("/") > -1) { fileName = fileFullName.substring(fileFullName.lastIndexOf("/") + 1, fileFullName.length()); filePath = fileFullName.substring(0, fileFullName.lastIndexOf("/")); } else if (fileFullName.indexOf("\\") > -1) { fileName = fileFullName.substring(fileFullName.lastIndexOf("\\") + 1, fileFullName.length()); filePath = fileFullName.substring(0, fileFullName.lastIndexOf("\\")); } jsonObj.put("filePath", filePath); jsonObj.put("fileName", fileName); } /** * Exports the job specified by job name * * @param p_accessToken * @param p_jobName * String Job name * @return String in JSON. A sample is like: * {"status":"Export Request Sent","workflowLocale":"All Locales","jobName":"3801_656474062"} * @throws WebServiceException */ public String exportJob(String p_accessToken, String p_jobName) throws WebServiceException { checkAccess(p_accessToken, EXPORT_JOB); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.JOBS_EXPORT); if (StringUtil.isNotEmpty(returnStr)) return returnStr; String jobName = p_jobName; WebServicesLog.Start activityStart = null; JSONObject jsonObj = new JSONObject(); try { String userName = getUsernameFromSession(p_accessToken); Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", userName); activityArgs.put("jobName", p_jobName); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "exportJob(p_accessToken, p_jobName)", activityArgs); Job job = queryJob(jobName, p_accessToken, jsonObj); if (job.getDisplayState().equalsIgnoreCase("ready")) { return makeErrorJson(EXPORT_JOB, p_jobName + " is ready state , can not be export."); } Object[] workflows = job.getWorkflows().toArray(); long projectId = job.getL10nProfile().getProject().getId(); User projectMgr = ServerProxy.getProjectHandler().getProjectById(projectId).getProjectManager(); // export all workflow logger.info("Exporting all " + workflows.length + " workflows for job " + jobName); for (int i = 0; i < workflows.length; i++) { Workflow w = (Workflow) workflows[i]; if (!w.getState().equals(Workflow.IMPORT_FAILED) && !w.getState().equals(Workflow.CANCELLED)) { exportSingleWorkflow(job, w, projectMgr); } } jsonObj.put("jobName", EditUtil.encodeXmlEntities(jobName)); jsonObj.put("workflowLocale", "All Locales"); jsonObj.put("status", "Export Request Sent"); return jsonObj.toString(); } catch (Exception e) { logger.error("exportJob()", e); String message = "Could not export job " + jobName; return makeErrorJson(EXPORT_JOB, message); } finally { if (activityStart != null) { activityStart.end(); } } } /** * Exports the job. If p_workflowLocale is null then all pages for all * workflows are exported, otherwise the specific workflow corresponding to * the locale is exported. * * @param p_jobName * -- name of job * @param p_workflowLocale * -- locale of workflow to export * @return String in JSON. A sample is like: * {"status":"Export Request Sent","workflowLocale":"de_DE","jobName":"3801_656474062"} * @exception WebServiceException */ public String exportWorkflow(String p_accessToken, String p_jobName, String p_workflowLocale) throws WebServiceException { checkAccess(p_accessToken, EXPORT_WORKFLOW); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.JOB_WORKFLOWS_EXPORT); if (StringUtil.isNotEmpty(returnStr)) return returnStr; String jobName = p_jobName; String workflowLocale = p_workflowLocale; String returnXml = ""; WebServicesLog.Start activityStart = null; JSONObject jsonObj = new JSONObject(); try { String userName = getUsernameFromSession(p_accessToken); Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", userName); activityArgs.put("jobName", p_jobName); activityArgs.put("workflowLocale", p_workflowLocale); activityStart = WebServicesLog.start(Ambassador.class, "exportWorkflow(p_accessToken, p_jobName,p_workflowLocale)", activityArgs); Job job = queryJob(jobName, p_accessToken, jsonObj); Object[] workflows = job.getWorkflows().toArray(); long projectId = job.getL10nProfile().getProject().getId(); User projectMgr = ServerProxy.getProjectHandler().getProjectById(projectId).getProjectManager(); boolean didExport = false; if (workflowLocale == null) { // export all workflow logger.info("Exporting all " + workflows.length + " workflows for job " + jobName); for (int i = 0; i < workflows.length; i++) { Workflow w = (Workflow) workflows[i]; if (!w.getState().equals(Workflow.IMPORT_FAILED) && !w.getState().equals(Workflow.CANCELLED)) { exportSingleWorkflow(job, w, projectMgr); } } didExport = true; } else { // export just one workflow Locale locale = GlobalSightLocale.makeLocaleFromString(workflowLocale); logger.info("Job " + jobName + " has " + workflows.length + " workflow."); for (int i = 0; i < workflows.length; i++) { Workflow w = (Workflow) workflows[i]; Locale wLocale = w.getTargetLocale().getLocale(); if (locale.equals(wLocale)) { exportSingleWorkflow(job, w, projectMgr); didExport = true; break; } } } if (didExport == false) throw new Exception("No workflow for locale " + workflowLocale); jsonObj.put("jobName", EditUtil.encodeXmlEntities(jobName)); if (workflowLocale == null) jsonObj.put("workflowLocale", "All Locales"); else jsonObj.put("workflowLocale", workflowLocale); jsonObj.put("status", "Export Request Sent"); returnXml = jsonObj.toString(); } catch (Exception e) { logger.error("exportWorkflow()", e); String message = "Could not export workflow for job " + jobName; return makeErrorJson(EXPORT_WORKFLOW, message); } finally { if (activityStart != null) { activityStart.end(); } } return returnXml; } /** * Get exported job files (do not care if the workflow is "EXPORTED") * * @param p_accessToken * Access token * @param p_jobName * Job name * @return String in JSON. A sample is like: * {"paths":["de_DE/17/accuracy_test_results.htm","de_DE/17/multiple_channels.htm","de_DE/17/stability_test_results.htm"],"root":"http://10.10.215.38:8080/globalsight/cxedocs/allie"} * @throws WebServiceException */ public String getJobExportFiles(String p_accessToken, String p_jobName) throws WebServiceException { checkAccess(p_accessToken, GET_JOB_EXPORT_FILES); String jobsView = checkPermissionReturnStr(p_accessToken, Permission.JOBS_VIEW); if (StringUtil.isNotEmpty(jobsView)) return jobsView; String jobsExport = checkPermissionReturnStr(p_accessToken, Permission.JOBS_EXPORT); if (StringUtil.isNotEmpty(jobsExport)) return jobsExport; String jobName = p_jobName; WebServicesLog.Start activityStart = null; JSONObject jsonObj = new JSONObject(); Job job = queryJob(jobName, p_accessToken, jsonObj); String jobCompanyId = String.valueOf(job.getCompanyId()); String curUserName = getUsernameFromSession(p_accessToken); User curUser = getUser(curUserName); Company curCompany = getCompanyByName(curUser.getCompanyName()); if (curCompany.getId() != 1 && !isInSameCompany(curUserName, jobCompanyId)) throw new WebServiceException( "Current user is not super user,cannot access the job which is not in the same company with current user"); String status = job.getState(); if (status == null) { return makeErrorJson(GET_JOB_EXPORT_FILES, "Job " + jobName + " does not exist."); } JobFiles jobFiles = new JobFiles(); StringBuilder prefix = new StringBuilder(); prefix.append(getUrl()).append("/cxedocs/"); String company = CompanyWrapper.getCompanyNameById(job.getCompanyId()); prefix.append(URLEncoder.encode(company, "utf-8")); jobFiles.setRoot(prefix.toString()); Set<String> passoloFiles = new HashSet<String>(); long fileProfileId = -1l; FileProfile fp = null; FileProfilePersistenceManager fpManager = null; boolean isXLZFile = false; try { fpManager = ServerProxy.getFileProfilePersistenceManager(); } catch (Exception e) { logger.error("Cannot get file profile manager.", e); return makeErrorJson(GET_JOB_EXPORT_FILES, "Cannot get file profile manager." + e.getMessage()); } try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", curUserName); activityArgs.put("jobName", p_jobName); activityStart = WebServicesLog.start(Ambassador.class, "getJobExportFiles(p_accessToken, p_jobName)", activityArgs); for (Workflow w : job.getWorkflows()) { if (Workflow.CANCELLED.equals(w.getState()) || Workflow.PENDING.equals(w.getState()) || Workflow.EXPORT_FAILED.equals(w.getState()) || Workflow.IMPORT_FAILED.equals(w.getState())) continue; ArrayList<String> fileList = new ArrayList<String>(); for (TargetPage page : w.getTargetPages()) { SourcePage sPage = page.getSourcePage(); if (sPage != null && sPage.isPassoloPage()) { String p = sPage.getPassoloFilePath(); p = p.replace("\\", "/"); p = p.substring(p.indexOf("/") + 1); passoloFiles.add(p); if (fileList.contains(p)) continue; else { fileList.add(p); } continue; } fileProfileId = sPage.getRequest().getFileProfileId(); fp = fpManager.getFileProfileById(fileProfileId, false); if (fpManager.isXlzReferenceXlfFileProfile(fp.getName())) isXLZFile = true; String path = page.getExternalPageId(); path = path.replace("\\", "/"); if (StringUtil.isNotEmpty(fp.getScriptOnExport())) { path = handlePathForScripts(path, job); } int index = path.indexOf("/"); path = path.substring(index); path = getRealFilePathForXliff(path, isXLZFile); if (fileList.contains(path)) continue; else { fileList.add(path); } StringBuffer allPath = new StringBuffer(); allPath.append(page.getGlobalSightLocale()); for (String s : path.split("/")) { if (s.length() > 0) { allPath.append("/").append(URLEncoder.encode(s, "utf-8")); } } jobFiles.addPath(allPath.toString()); isXLZFile = false; } } for (String path : passoloFiles) { StringBuffer allPath = new StringBuffer(); allPath.append("passolo"); for (String s : path.split("/")) { if (s.length() > 0) { allPath.append("/").append(URLEncoder.encode(s, "utf-8")); } } jobFiles.addPath(allPath.toString()); } JSONArray array = new JSONArray(); List<String> listPaths = jobFiles.getPaths(); for (String paths : listPaths) { array.put(paths); } jsonObj.put("paths", array); String root = jobFiles.getRoot(); jsonObj.put("root", root); return jsonObj.toString(); } catch (Exception e) { logger.error("Error found in getJobExportFiles.", e); return makeErrorJson(GET_JOB_EXPORT_FILES, e.getMessage()); } finally { if (activityStart != null) { activityStart.end(); } } } /** * Return exported files information for job's "EXPORTED" state workflows. * * @param p_accessToken * Access token * @param p_jobName * Job name * @param workflowLocale * Locale of workflow, it can accept fr_FR, fr-FR, fr_fr formats * If it is null, all "EXPORTED" workflows' exported files info * will be returned. * @return String in JSON. A sample is like: * {"paths":["de_DE/17/accuracy_test_results.htm","de_DE/17/multiple_channels.htm","de_DE/17/stability_test_results.htm"],"root":"http://10.10.215.38:8080/globalsight/cxedocs/allie"} * @throws WebServiceException */ public String getJobExportWorkflowFiles(String p_accessToken, String p_jobName, String workflowLocale) throws WebServiceException { checkAccess(p_accessToken, GET_JOB_EXPORT_WORKFLOW_FILES); String jobsView = checkPermissionReturnStr(p_accessToken, Permission.JOBS_VIEW); if (StringUtil.isNotEmpty(jobsView)) return jobsView; String jobsExport = checkPermissionReturnStr(p_accessToken, Permission.JOBS_EXPORT); if (StringUtil.isNotEmpty(jobsExport)) return jobsExport; WebServicesLog.Start activityStart = null; JSONObject jsonObj = new JSONObject(); String jobName = p_jobName; Job job = queryJob(jobName, p_accessToken, jsonObj); String jobCompanyId = String.valueOf(job.getCompanyId()); String curUserName = getUsernameFromSession(p_accessToken); User curUser = getUser(curUserName); Company curCompany = getCompanyByName(curUser.getCompanyName()); if (curCompany.getId() != 1 && !isInSameCompany(curUserName, jobCompanyId)) throw new WebServiceException( "Current user is not super user,cannot access the job which is not in the same company with current user"); String status = job.getState(); if (status == null) { return makeErrorJson(GET_JOB_EXPORT_WORKFLOW_FILES, "Job " + jobName + " does not exist."); } JobFiles jobFiles = new JobFiles(); long fileProfileId = -1l; FileProfile fp = null; FileProfilePersistenceManager fpManager = null; boolean isXLZFile = false; try { fpManager = ServerProxy.getFileProfilePersistenceManager(); } catch (Exception e) { logger.error("Cannot get file profile manager.", e); return makeErrorJson(GET_JOB_EXPORT_WORKFLOW_FILES, "Cannot get file profile manager." + e.getMessage()); } StringBuilder prefix = new StringBuilder(); prefix.append(getUrl()).append("/cxedocs/"); String company = CompanyWrapper.getCompanyNameById(job.getCompanyId()); prefix.append(URLEncoder.encode(company, "utf-8")); jobFiles.setRoot(prefix.toString()); Set<String> passoloFiles = new HashSet<String>(); try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", curUserName); activityArgs.put("jobName", p_jobName); activityArgs.put("workflowLocale", workflowLocale); activityStart = WebServicesLog.start(Ambassador.class, "getJobExportWorkflowFiles(p_accessToken, p_jobName,workflowLocale)", activityArgs); for (Workflow w : job.getWorkflows()) { if (StringUtil.isEmpty(workflowLocale)) { // need to download all 'Exported' workflow files if (!Workflow.EXPORTED.equals(w.getState())) continue; } else { // download workflow files if (!isWorkflowOfLocaleExported(w, workflowLocale)) continue; } ArrayList<String> fileList = new ArrayList<String>(); for (TargetPage page : w.getTargetPages()) { SourcePage sPage = page.getSourcePage(); if (sPage != null && sPage.isPassoloPage()) { String p = sPage.getPassoloFilePath(); p = p.replace("\\", "/"); p = p.substring(p.indexOf("/") + 1); passoloFiles.add(p); if (fileList.contains(p)) continue; else { fileList.add(p); } continue; } fileProfileId = sPage.getRequest().getFileProfileId(); fp = fpManager.getFileProfileById(fileProfileId, false); if (fpManager.isXlzReferenceXlfFileProfile(fp.getName())) isXLZFile = true; String path = page.getExternalPageId(); path = path.replace("\\", "/"); if (StringUtil.isNotEmpty(fp.getScriptOnExport())) { path = handlePathForScripts(path, job); } int index = path.indexOf("/"); path = path.substring(index); path = getRealFilePathForXliff(path, isXLZFile); if (fileList.contains(path)) continue; else { fileList.add(path); } StringBuffer allPath = new StringBuffer(); allPath.append(page.getGlobalSightLocale()); for (String s : path.split("/")) { if (s.length() > 0) { allPath.append("/").append(URLEncoder.encode(s, "utf-8")); } } jobFiles.addPath(allPath.toString()); } } for (String path : passoloFiles) { StringBuffer allPath = new StringBuffer(); allPath.append("passolo"); for (String s : path.split("/")) { if (s.length() > 0) { allPath.append("/").append(URLEncoder.encode(s, "utf-8")); } } jobFiles.addPath(allPath.toString()); } JSONArray array = new JSONArray(); List<String> listPaths = jobFiles.getPaths(); for (String paths : listPaths) { array.put(paths); } jsonObj.put("paths", array); String root = jobFiles.getRoot(); jsonObj.put("root", root); return jsonObj.toString(); } catch (Exception e) { logger.error("Error found in " + GET_JOB_EXPORT_WORKFLOW_FILES, e); return makeErrorJson(GET_JOB_EXPORT_WORKFLOW_FILES, e.getMessage()); } finally { if (activityStart != null) { activityStart.end(); } } } private String handlePathForScripts(String path, Job job) { path = path.replace("\\", "/"); String finalPath = path; // for new scripts on import/export if (path.contains("/PreProcessed_" + job.getId() + "_")) { finalPath = path.replace( path.substring(path.lastIndexOf("/PreProcessed_" + job.getId() + "_"), path.lastIndexOf("/")), ""); } // compatible codes for old import/export else { int index = path.lastIndexOf("/"); if (index > -1) { String fileName = path.substring(index + 1); String extension = fileName.substring(fileName.lastIndexOf(".") + 1); fileName = fileName.substring(0, fileName.lastIndexOf(".")); String rest = path.substring(0, index); if (rest.endsWith("/" + fileName)) { finalPath = rest + "." + extension; } } } return finalPath; } private boolean isWorkflowOfLocaleExported(Workflow workflow, String locale) { if (workflow == null || StringUtil.isEmpty(locale)) return false; String workflowState = workflow.getState(); if (!workflowState.equals(Workflow.EXPORTED)) return false; String lowerWorkflowLocale = workflow.getTargetLocale().toString().toLowerCase(); String lowerLocale = locale.replace('-', '_').toLowerCase(); if (lowerWorkflowLocale.equals(lowerLocale)) return true; else return false; } private String getUrl() { return AmbassadorUtil.getCapLoginOrPublicUrl(); } private String getRealFilePathForXliff(String path, boolean isXLZFile) { if (StringUtil.isEmpty(path)) return path; int index = -1; index = path.lastIndexOf(".sub/"); if (index > 0) { // one big xliff file is split to some sub-files path = path.substring(0, index); } if (isXLZFile) { path = path.substring(0, path.lastIndexOf("/")); path += ".xlz"; } return path; } /** * Check if the company info of job or project is the same with current user */ private boolean isInSameCompany(String p_userName, String p_companyId) { if (p_userName == null || p_userName.trim().equals("")) return false; if (p_companyId == null || p_companyId.trim().equals("")) return false; try { User user = ServerProxy.getUserManager().getUserByName(p_userName); String userCompanyId = ServerProxy.getJobHandler().getCompany(user.getCompanyName()).getIdAsLong() .toString(); return userCompanyId.equals(p_companyId) ? true : false; } catch (Exception e) { return false; } } /** * Exports all target pages of the given workflow * * @param p_job * Entity of Job * @param p_workflow * Entity of Workflow * @param p_user * Specified user information * @throws Exception */ private void exportSingleWorkflow(Job p_job, Workflow p_workflow, User p_user) throws Exception { List targetPages = p_workflow.getTargetPages(); ArrayList pageIds = new ArrayList(); for (int j = 0; j < targetPages.size(); j++) { TargetPage tp = (TargetPage) targetPages.get(j); pageIds.add(tp.getIdAsLong()); } ExportParameters ep = new ExportParameters(p_workflow); boolean isTargetPage = true; ArrayList wfIds = new ArrayList(); wfIds.add(p_workflow.getIdAsLong()); Long taskId = null; logger.info("Exporting workflow " + p_workflow.getTargetLocale().toString() + " for job " + p_job.getJobName()); long exportBatchId = ServerProxy.getExportEventObserver().notifyBeginExportTargetBatch(p_job, p_user, pageIds, wfIds, taskId, ExportBatchEvent.INTERIM_PRIMARY); ServerProxy.getPageManager().exportPage(ep, pageIds, isTargetPage, exportBatchId); } /** * Gets out the Job object corresponding to the job name assuming that is * unique * * @param p_jobName * Job name * @param p_accessToken * @return Job Return job object if there exist. * @exception WebServiceException */ private Job queryJob(String p_jobName, String p_accessToken, JSONObject jsonObj) throws WebServiceException { Connection connection = null; PreparedStatement query = null; ResultSet results = null; try { connection = ConnectionPool.getConnection(); String condition = appendJobCondition(p_jobName); User user = getUser(getUsernameFromSession(p_accessToken)); long companyId = CompanyWrapper.getCompanyByName(user.getCompanyName()).getId(); String sql = null; if (companyId != 1) { sql = "SELECT ID FROM JOB WHERE COMPANY_ID=? AND " + condition; query = connection.prepareStatement(sql); query.setLong(1, companyId); query.setString(2, p_jobName); } else { sql = "SELECT ID FROM JOB WHERE " + condition; query = connection.prepareStatement(sql); query.setString(1, p_jobName); } results = query.executeQuery(); if (results.next()) { long id = results.getLong(1); Job job = ServerProxy.getJobHandler().getJobById(id); return job; } else { String message = NOT_IN_DB + p_jobName; message = jsonObj.put("queryJob", message).toString(); /* * Do not change this Exception message "This job is not ready * for query", because getStatus() will deal with it in * catch(Exception e) and Desktop Icon * * com/globalsight/action/AddCommentAction.java : * executeWithThread(String args[]) */ throw new WebServiceException(message); } } catch (ConnectionPoolException cpe) { String message = "Unable to connect to database to get job status."; logger.error(message, cpe); try { message = jsonObj.put("queryJob", message).toString(); } catch (JSONException e) { e.printStackTrace(); } throw new WebServiceException(message); } catch (SQLException sqle) { String message = "Unable to query DB for job status."; logger.error(message, sqle); try { message = jsonObj.put("queryJob", message).toString(); } catch (JSONException e) { e.printStackTrace(); } throw new WebServiceException(message); } catch (WebServiceException le) { throw le; } catch (Exception e) { String message = "Unable to get job information from System4."; logger.error(message, e); try { message = jsonObj.put("queryJob", message).toString(); } catch (JSONException e1) { e1.printStackTrace(); } throw new WebServiceException(message); } finally { releaseDBResource(results, query, connection); } } private String appendJobCondition(String p_jobName) { String condition = "NAME=?"; try { int index = p_jobName.lastIndexOf("_"); if (index > -1) { String random = p_jobName.substring(index + 1); if (random != null && random.length() > 6 && StringUtils.isNumeric(random)) { condition = "(NAME=? OR NAME LIKE '%" + random + "')"; } } } catch (Exception ignore) { } return condition; } /** * Create new user * * @param p_accessToken * String Access token. REQUIRED. * @param p_userId * String User ID. REQUIRED. * Example: 'qaadmin' * @param p_password * String Password. It requires 8 characters at least. REQUIRED. * @param p_firstName * String First name. It can have 100 characters at most. REQUIRED. * @param p_lastName * String Last name. It can have 100 characters at most. REQUIRED. * @param p_email * String Email address. REQUIRED. * If the email address is not vaild then the user's status will be set up as inactive * @param p_permissionGrps * String[] Permission groups which the new user belongs to. * The element in the array is the name of permission group. * Example: [{"Administrator"}, {"ProjectManager"}] * @param p_roles * Roles String information of user. It uses a string with XML format to mark all roles information of user. REQUIRED. * Example: * <?xml version=\"1.0\"?> * <roles> * <role> * <sourceLocale>en_US</sourceLocale> * <targetLocale>de_DE</targetLocale> * <activities> * <activity> * <name>Dtp1</name> * </activity> * <activity> * <name>Dtp2</name> * </activity> * </activities> * </role> * </roles> * If super user create user,Roles Example: * <?xml version=\"1.0\"?> * <roles> * <role> * <companyName>allie</companyName> * <sourceLocale>en_US</sourceLocale> * <targetLocale>de_DE</targetLocale> * <activities> * <activity> * <name>Dtp1</name> * </activity> * <activity> * <name>Dtp2</name> * </activity> * </activities> * </role> * </roles> * @param p_isInAllProject * boolean If the user need to be included in all project. REQUIRED. * @param p_projectIds * String[] ID of projects which user should be included in. If p_isInAllProject is true, this will not take effect. * Example: [{"1"}, {"3"}] * @return int Return code * 0 -- Success * 1 -- Invalid access token * 2 -- Invalid user id * 3 -- Cannot create super user * 4 -- User exists * 5 -- User does NOT exist * 6 -- User is NOT in the same company with logged user * 7 -- Invalid user password * 8 -- Invalid first name * 9 -- Invalid last name * 10 -- Invalid email address * 11 -- Invalid permission groups * 12 -- Invalid project information * 13 -- Invalid role information * 14-- Current login user does not have enough permission * -1 -- Unknown exception * @throws WebServiceException */ public int createUser(String p_accessToken, String p_userId, String p_password, String p_firstName, String p_lastName, String p_email, String[] p_permissionGrps, String p_roles, boolean p_isInAllProject, String[] p_projectIds) throws WebServiceException { AmbassadorHelper helper = new AmbassadorHelper(); return helper.createUser(p_accessToken, p_userId, p_password, p_firstName, p_lastName, p_email, p_permissionGrps, null, p_roles, p_isInAllProject, p_projectIds); } /** * Modify user * * @param p_accessToken * String Access token. REQUIRED. * @param p_userId * String User ID. REQUIRED. * Example: 'qaadmin' * @param p_password * String Password. It requires 8 characters at least. * @param p_firstName * String First name. It can have 100 characters at most. * @param p_lastName * String Last name. It can have 100 characters at most. * @param p_email * String Email address. * If the email address is invalid, the user status will be set up as inactive. * @param p_permissionGrps * String[] Permission groups which the new user belongs to. * The element in the array is the name of permission group. * Example: [{"Administrator"}, {"ProjectManager"}] * @param p_roles * Roles String information of user. It uses a string with XML format to mark all roles information of user. * Example: * <?xml version=\"1.0\"?> * <roles> * <role> * <sourceLocale>en_US</sourceLocale> * <targetLocale>de_DE</targetLocale> * <activities> * <activity> * <name>Dtp1</name> * </activity> * <activity> * <name>Dtp2</name> * </activity> * </activities> * </role> * </roles> * If super user modify user,Roles Example: * <?xml version=\"1.0\"?> * <roles> * <role> * <companyName>allie</companyName> * <sourceLocale>en_US</sourceLocale> * <targetLocale>de_DE</targetLocale> * <activities> * <activity> * <name>Dtp1</name> * </activity> * <activity> * <name>Dtp2</name> * </activity> * </activities> * </role> * </roles> * @param p_isInAllProject * boolean If the user need to be included in all project. REQUIRED. * @param p_projectIds * String[] ID of projects which user should be included in. If p_isInAllProject is true, this will not take effect. * Example: [{"1"}, {"3"}] * @return int Return code * 0 -- Success * 1 -- Invalid access token * 2 -- Invalid user id * 3 -- Cannot create super user * 4 -- User exists * 5 -- User does NOT exist * 6 -- User is NOT in the same company with logged user * 7 -- Invalid user password * 8 -- Invalid first name * 9 -- Invalid last name * 10 -- Invalid email address * 11 -- Invalid permission groups * 12 -- Invalid project information * 13 -- Invalid role information * 14-- Current login user does not have enough permission * -1 -- Unknown exception * @throws WebServiceException */ public int modifyUser(String p_accessToken, String p_userId, String p_password, String p_firstName, String p_lastName, String p_email, String[] p_permissionGrps, String p_roles, boolean p_isInAllProject, String[] p_projectIds) throws WebServiceException { AmbassadorHelper helper = new AmbassadorHelper(); return helper.modifyUser(p_accessToken, p_userId, p_password, p_firstName, p_lastName, p_email, p_permissionGrps, null, p_roles, p_isInAllProject, p_projectIds); } /** * Reassign task to other translators * * @param p_accessToken * String Access token * @param p_taskId * String ID of task * Example: "10" * @param p_users * String[] Users' information who will be reassigned to. The element in the array is [{userid}]. * Example: ["qaadmin", "qauser"] * @return * Return null if the reassignment executes successfully. * Otherwise, it will throw exception or return error message * @throws WebServiceException */ public String taskReassign(String p_accessToken, String p_taskId, String[] p_users) throws WebServiceException { AmbassadorHelper helper = new AmbassadorHelper(); return helper.taskReassign(p_accessToken, p_taskId, p_users); } /** * Get all workflow template basic information available to this user. * * @param p_accessToken * -- login user's token * @return -- String in JSON style, an example is: * [{"targetLocale":"German (Germany) [de_DE]","sourceLocale":"English (United States) [en_US]","projectManagerId":"yorkadmin","workflowTemplateName":"en_US_de_DE_T","companyName":"Welocalize","projectName":"Project_A"}, * {"targetLocale":"German (Germany) [de_DE]","sourceLocale":"English (United States) [en_US]","projectManagerId":"yorkadmin","workflowTemplateName":"en_US_de_DE_TR","companyName":"Welocalize","projectName":"Project_A"}] * * @throws WebServiceException */ @SuppressWarnings("unchecked") public String getWorkflowTemplateNames(String p_accessToken) throws WebServiceException { checkAccess(p_accessToken, GET_WORKFLOW_TEMPLATE_NAMES); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.WORKFLOWS_VIEW); if (StringUtil.isNotEmpty(returnStr)) return returnStr; String json = ""; try { WfTemplateSearchParameters params = new WfTemplateSearchParameters(); List<WorkflowTemplateInfo> templates = (List<WorkflowTemplateInfo>) ServerProxy.getProjectHandler() .findWorkflowTemplates(params); if (templates == null || templates.size() < 1) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_NAMES, "Cannot get workflow template names correctly."); } Locale uiLocale = getUILocale(p_accessToken); JSONArray array = new JSONArray(); for (WorkflowTemplateInfo wftInfo : templates) { JSONObject jsonObj = new JSONObject(); jsonObj.put("workflowTemplateName", wftInfo.getName()); jsonObj.put("projectName", wftInfo.getProject().getName()); jsonObj.put("sourceLocale", wftInfo.getSourceLocale().getDisplayName(uiLocale)); jsonObj.put("targetLocale", wftInfo.getTargetLocale().getDisplayName(uiLocale)); jsonObj.put("projectManagerId", wftInfo.getProjectManagerId()); String comName = ServerProxy.getJobHandler().getCompanyById(wftInfo.getCompanyId()) .getCompanyName(); jsonObj.put("companyName", comName); array.put(jsonObj); } json = array.toString(); } catch (Exception e) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_NAMES, "Cannot get workflow template names correctly." + e.getMessage()); } return json; } /** * Get a listing of the activity names and their assignees for the given * workflow template name and company name. * * @param p_accessToken * -- login user's token * @param p_workflowTemplateName * -- workflow template name * @param p_companyName * -- company name * @return String in JSON style, an example is: * [{"Participants":"yorkanyone","AvailableAssignees":"yorkanyone,yorkadmin,superpm","sequence":1,"activityName":"Translation1_2","IncomingArrows":"Action9","OutgoingArrows":"Action15"}, * {"Participants":"yorkadmin,superpm","AvailableAssignees":"yorkanyone,yorkadmin,superpm","sequence":2,"activityName":"review_linguistc1_2","IncomingArrows":"Action16","OutgoingArrows":"Action11"}] * * @throws WebServiceException * */ @SuppressWarnings("unchecked") public String getWorkflowTemplateInfo(String p_accessToken, String p_workflowTemplateName, String p_companyName) throws WebServiceException { checkAccess(p_accessToken, GET_WORKFLOW_TEMPLATE_INFO); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.WORKFLOWS_VIEW); if (StringUtil.isNotEmpty(returnStr)) return returnStr; if (StringUtil.isEmpty(p_workflowTemplateName)) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_INFO, "empty workflowTemplateName."); } if (StringUtil.isEmpty(p_companyName) || getCompanyByName(p_companyName) == null) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_INFO, "empty companyName or no such company '" + p_companyName + "'."); } User curUser = getUser(getUsernameFromSession(p_accessToken)); Company curcompany = getCompanyByName(curUser.getCompanyName()); if (curcompany.getId() != 1 && !curcompany.getName().equalsIgnoreCase(p_companyName)) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_INFO, "Invaild comoany name parameter."); } String json = ""; WebServicesLog.Start activityStart = null; try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("workflowTemplateName", p_workflowTemplateName); activityArgs.put("companyName", p_companyName); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "getWorkflowTemplateInfo(accessToken, workflowTemplateName, companyName)", activityArgs); WfTemplateSearchParameters params = new WfTemplateSearchParameters(); params.setWorkflowName(p_workflowTemplateName); List<WorkflowTemplateInfo> templates = (List<WorkflowTemplateInfo>) ServerProxy.getProjectHandler() .findWorkflowTemplates(params); if (templates == null || templates.size() < 1) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_INFO, "Cannot get WorkflowTemplateInfo with name '" + p_workflowTemplateName + "'."); } // Filter to ensure the template belongs to specified company. Company company = getCompanyByName(p_companyName); for (Iterator<WorkflowTemplateInfo> wftInfoIter = templates.iterator(); wftInfoIter.hasNext();) { WorkflowTemplateInfo wftInfo = wftInfoIter.next(); // If template is not in specified company, ignore it. if (wftInfo.getCompanyId() != company.getId()) { wftInfoIter.remove(); } } if (templates.size() < 1) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_INFO, "There is no workflow template that matches the name '" + p_workflowTemplateName + "' and company '" + p_companyName + "'."); } JSONArray array = new JSONArray(); // generally the size of "templates" should be 1. WorkflowTemplateInfo wftInfo = templates.get(0); String srcLocale = wftInfo.getSourceLocale().toString(); String trgLocale = wftInfo.getTargetLocale().toString(); Set<String> projectUserIds = wftInfo.getProject().getUserIds(); WorkflowTemplate wfTemplate = WorkflowTemplateHandlerHelper .getWorkflowTemplateById(wftInfo.getWorkflowTemplateId()); Vector<WorkflowTask> wfTasks = wfTemplate.getWorkflowTasks(); for (WorkflowTask wfTask : wfTasks) { if (wfTask.getType() == WorkflowConstants.ACTIVITY) { JSONObject jsonObj = new JSONObject(); jsonObj.put("activityName", wfTask.getActivityName()); jsonObj.put("sequence", wfTask.getSequence()); String displayRoleName = wfTask.getDisplayRoleName(); if (WorkflowTask.DEFAULT_ROLE_NAME.equalsIgnoreCase(displayRoleName)) { jsonObj.put("Participants", WorkflowTask.DEFAULT_ROLE_NAME); } else { String participantUserIds = convertParticipantUserNamesToIds(displayRoleName); jsonObj.put("Participants", participantUserIds); } String allAvailableAssignees = AmbassadorUtil.listToString(getAllAvailableAssigneeIds( wfTask.getActivityName(), srcLocale, trgLocale, projectUserIds)); jsonObj.put("AvailableAssignees", allAvailableAssignees); StringBuffer inArrows = new StringBuffer(); Vector incomingArrows = wfTask.getIncomingArrows(); if (incomingArrows != null && incomingArrows.size() > 0) { for (int i = 0; i < incomingArrows.size(); i++) { WorkflowArrow arrow = (WorkflowArrow) incomingArrows.get(i); inArrows.append(arrow.getName()); if (i + 1 < incomingArrows.size()) { inArrows.append(","); } } } jsonObj.put("IncomingArrows", inArrows.toString()); StringBuffer outArrows = new StringBuffer(); getOutgoingArrows(outArrows, wfTask); String outArrowNames = outArrows.toString(); if (outArrowNames.length() > 0 && outArrowNames.endsWith(",")) { outArrowNames = outArrowNames.substring(0, outArrowNames.length() - 1); } jsonObj.put("OutgoingArrows", outArrowNames); array.put(jsonObj); } } json = array.toString(); } catch (Exception e) { return makeErrorJson(GET_WORKFLOW_TEMPLATE_INFO, "Cannot get workflow template info correctly. " + e.getMessage()); } finally { if (activityStart != null) { activityStart.end(); } } return json; } /** * Get the outgoing arrow names comma separated. If the arrow points to a * condition node, then the condition node's outgoing arrows are wanted. * * @param buf * @param wfTask */ private void getOutgoingArrows(StringBuffer buf, WorkflowTask wfTask) { Vector outgoingArrows = wfTask.getOutgoingArrows(); if (outgoingArrows != null && outgoingArrows.size() > 0) { for (int i = 0; i < outgoingArrows.size(); i++) { WorkflowArrow arrow = (WorkflowArrow) outgoingArrows.get(i); WorkflowTask targetWfTask = arrow.getTargetNode(); if ("Condition Node".equalsIgnoreCase(targetWfTask.getName())) { getOutgoingArrows(buf, targetWfTask); } else { buf.append(arrow.getName()).append(","); } } } } /** * For a given workflow template name, activity name list, adjust the * assignees. Also allow "all qualified users" as a parameter. If no valid * assignees, also use "all qualified users" as default. * * @param p_accessToken * -- login user's token * @param p_workflowTemplateName * -- workflow template name * @param p_companyName * -- company name * @param p_activityAssigneesInJson * -- activity assignees to be updated in JSON. A sample is: * [{"Participants":"All qualified users","activityName":"Translation1_2","sequence":"1"},{"Participants":"yorkadmin","activityName":"review_linguistc1_2","sequence":"2"}] * * @return String in JSON style for error.If success, return nothing. * * @throws WebServiceException */ @SuppressWarnings("unchecked") public String modifyWorkflowTemplateAssignees(String p_accessToken, String p_workflowTemplateName, String p_companyName, String p_activityAssigneesInJson) throws WebServiceException { checkAccess(p_accessToken, MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES); String returnStr = checkPermissionReturnStr(p_accessToken, Permission.WORKFLOWS_VIEW); if (StringUtil.isNotEmpty(returnStr)) return returnStr; // Parameters checking if (StringUtil.isEmpty(p_workflowTemplateName)) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "empty workflowTemplateName."); } if (StringUtil.isEmpty(p_companyName) || getCompanyByName(p_companyName) == null) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "empty companyName or no such company."); } if (StringUtil.isEmpty(p_activityAssigneesInJson)) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "empty activityAssigneesInJson."); } Company company = getCompanyByName(p_companyName); User curUser = getUser(getUsernameFromSession(p_accessToken)); Company companyOfLogUser = getCompanyByName(curUser.getCompanyName()); if (companyOfLogUser.getId() != 1 && companyOfLogUser.getId() != company.getId()) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "Logged user can only access workflows of its own company, can not access another company's data."); } // Activity-Assignees to be updated HashMap<Integer, JSONObject> seq2JsonObjMap = new HashMap<Integer, JSONObject>(); try { JSONArray array = new JSONArray(p_activityAssigneesInJson.trim()); if (array.length() < 1) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "No activity assignees need to be changed according to 'activityAssigneesInJson' parameter: " + p_activityAssigneesInJson); } for (int i = 0; i < array.length(); i++) { JSONObject obj = array.getJSONObject(i); seq2JsonObjMap.put(obj.getInt("sequence"), obj); } } catch (JSONException jsonEx) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "Fail to get JSONArray from 'activityAssigneesInJson' parameter: " + p_activityAssigneesInJson); } StringBuffer json = new StringBuffer(); WebServicesLog.Start activityStart = null; try { // WebServicesLog Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("workflowTemplateName", p_workflowTemplateName); activityArgs.put("companyName", p_companyName); activityArgs.put("activityAssigneesInJson", p_activityAssigneesInJson); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "modifyWorkflowTemplateAssignees(accessToken, workflowTemplateName, companyName, activityAssigneesInJson)", activityArgs); // Possible "WorkflowTemplateInfo" WfTemplateSearchParameters params = new WfTemplateSearchParameters(); params.setWorkflowName(p_workflowTemplateName.trim()); params.setCompanyName(p_companyName); List<WorkflowTemplateInfo> templates = (List<WorkflowTemplateInfo>) ServerProxy.getProjectHandler() .findWorkflowTemplates(params); if (templates == null || templates.size() < 1) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "Cannot get WorkflowTemplateInfo with name '" + p_workflowTemplateName + "'."); } // Filter to ensure the template belongs to specified company. for (Iterator<WorkflowTemplateInfo> wftInfoIter = templates.iterator(); wftInfoIter.hasNext();) { WorkflowTemplateInfo wftInfo = wftInfoIter.next(); // If template is not in specified company, ignore it. if (wftInfo.getCompanyId() != company.getId()) { wftInfoIter.remove(); } } if (templates.size() < 1) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "There is no workflow template that matches the name '" + p_workflowTemplateName + "' and company '" + p_companyName + "'."); } // Generally the size of "templates" should be 1. WorkflowTemplateInfo wftInfo = templates.get(0); String srcLocale = wftInfo.getSourceLocale().toString(); String trgLocale = wftInfo.getTargetLocale().toString(); WorkflowTemplate wfTemplate = WorkflowTemplateHandlerHelper .getWorkflowTemplateById(wftInfo.getWorkflowTemplateId()); Vector<WorkflowTask> wfTasks = wfTemplate.getWorkflowTasks(); Iterator<Entry<Integer, JSONObject>> it = seq2JsonObjMap.entrySet().iterator(); while (it.hasNext()) { Entry<Integer, JSONObject> act = it.next(); int sequence = act.getKey(); JSONObject object = act.getValue(); String activityName = object.getString("activityName"); boolean activityFound = false; for (WorkflowTask wfTask : wfTasks) { if (activityName != null && activityName.equals(wfTask.getActivityName()) && sequence == wfTask.getSequence()) { activityFound = true; String participants = object.getString("Participants"); if (WorkflowTask.DEFAULT_ROLE_NAME.equalsIgnoreCase(participants)) { updateWorkflowTaskToDefault(wfTask, srcLocale, trgLocale); } else { List<String> finalValidUserIds = getFinalValidUserIdsFromParticipants(wftInfo, wfTask, participants); if (finalValidUserIds.size() > 0) { wfTask.setDisplayRoleName( getFinalValidUserNamesFromParticipants(finalValidUserIds)); // On activity properties applet UI, if select // "A selected user...", this should be true. wfTask.setRoleType(true);// wfTask.setRolePreference(null); String[] roles = new String[finalValidUserIds.size()]; for (int i = 0; i < finalValidUserIds.size(); i++) { roles[i] = getRole(true, wfTask, srcLocale, trgLocale, finalValidUserIds.get(i)); } wfTask.setRoles(roles); } else { json.append("No valid participants(").append(participants) .append(") for activityName(").append(activityName) .append(") and sequence (").append(sequence).append(");"); } } break; } } if (!activityFound) { json.append("No such activity in workflow for activityName(").append(activityName) .append(") and sequence (").append(sequence).append(");"); } } // Save the changes. String[] wfManagerIds = new String[wftInfo.getWorkflowManagerIds().size()]; wfManagerIds = (String[]) wftInfo.getWorkflowManagerIds().toArray(wfManagerIds); WorkflowTemplate newWft = ServerProxy.getWorkflowServer().modifyWorkflowTemplate(wfTemplate, new WorkflowOwners(wftInfo.getProjectManagerId(), wfManagerIds)); wftInfo.setWorkflowTemplate(newWft); ServerProxy.getProjectHandler().modifyWorkflowTemplate(wftInfo); } catch (Exception e) { return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, "Error when try to modifyWorkflowTemplateAssignees. " + e.getMessage()); } finally { if (activityStart != null) { activityStart.end(); } } if (json.length() == 0) json.append("successful"); return makeErrorJson(MODIFY_WORKFLOW_TEMPLATE_ASSIGNEES, json.toString()); } /** * The "displayRoleName" is composed of user names instead of user IDs, need * return userId here. * * For "getWorkflowTemplateInfo(..)" API. * * @param p_displayRoleName */ private String convertParticipantUserNamesToIds(String p_displayRoleName) { if (StringUtil.isEmpty(p_displayRoleName)) return ""; String[] userNamesArray = stringToArray(p_displayRoleName); String[] userIdsArray = UserUtil.convertUserNamesToUserIds(userNamesArray); return arrayToString(userIdsArray); } /** * Get all available assignees for specified activity/source locale/target * locale. * * @param activityName * -- like "Translation1_2". * @param sourceLocale * -- like "EN_US"(case-insensitive). * @param targetLocale * -- like "ZH_CN"(case-insensitive). * @param projectUserIds * -- user Ids current project has. * @return -- HashSet<String> */ @SuppressWarnings("rawtypes") private HashSet<String> getAllAvailableAssigneeIds(String activityName, String sourceLocale, String targetLocale, Set<String> projectUserIds) { HashSet<String> results = new HashSet<String>(); Collection usersInRole = WorkflowTemplateHandlerHelper.getUserRoles(activityName, sourceLocale, targetLocale); if (usersInRole != null && usersInRole.size() > 0) { Vector<UserRoleImpl> validUserRoles = new Vector<UserRoleImpl>(); // filter out the users that aren't in the project for (Iterator i = usersInRole.iterator(); i.hasNext();) { UserRoleImpl userRole = (UserRoleImpl) i.next(); if (projectUserIds.contains(userRole.getUser())) { validUserRoles.add(userRole); } } for (int i = 0; i < validUserRoles.size(); i++) { UserRoleImpl userRole = (UserRoleImpl) validUserRoles.get(i); results.add(userRole.getUser());//userId } } return results; } private String getFinalValidUserNamesFromParticipants(List<String> userIdsFromParticipants) { Object[] userNames = UserUtil.convertUserIdsToUserNames(listToArray(userIdsFromParticipants)); List<String> userNameList = new ArrayList<String>(); for (Object userName : userNames) { userNameList.add((String) userName); } return AmbassadorUtil.listToString(userNameList); } /** * User may send wrong user ID/name, or user ID/name that belongs to another * company. Filter to get final valid userIds. */ @SuppressWarnings("unchecked") private List<String> getFinalValidUserIdsFromParticipants(WorkflowTemplateInfo wftInfo, WorkflowTask wfTask, String participants) { String srcLocale = wftInfo.getSourceLocale().toString(); String trgLocale = wftInfo.getTargetLocale().toString(); Set<String> projectUserIds = wftInfo.getProject().getUserIds(); HashSet<String> availableUserIds = getAllAvailableAssigneeIds(wfTask.getActivityName(), srcLocale, trgLocale, projectUserIds); Set<String> result = getValidUserIdsFromParticipants(participants); for (Iterator<String> it = result.iterator(); it.hasNext();) { // If is not available user, ignore it. if (!availableUserIds.contains(it.next())) { it.remove(); } } return new ArrayList<String>(result); } /** * Client may send user ID or Name to API, check to return valid user Ids * here. */ private Set<String> getValidUserIdsFromParticipants(String p_participants) { if (StringUtil.isEmpty(p_participants)) return null; Set<String> userIds = new HashSet<String>(); List<String> list = stringToList(p_participants); for (Iterator<String> it = list.iterator(); it.hasNext();) { try { String userIdOrName = it.next(); User user = UserUtil.getUserById(userIdOrName); // userIdOrName is a valid userId. if (user != null) { userIds.add(user.getUserId()); } else { String userId = UserUtil.getUserIdByName(userIdOrName); // userIdOrName is a valid userName. if (userId != null) { userIds.add(userId); } } } catch (Exception e) { // ignore } } return userIds; } /** * <p> * If specify users, it can has multiple roles(comma saparated), a role * sample is like * "1 Translation1_2 en_US zh_CN yorkadmin,1 Translation1_2 en_US zh_CN yorkanyone" * </p> * <p> * If not specify users, it only has one role, a sample is: * "1 Translation1_2 en_US zh_CN". * </p> */ private String getRole(boolean isUserRole, WorkflowTask wfTask, String srcLocale, String trgLocale, String userId) { StringBuilder role = new StringBuilder(); role.append(wfTask.getActivity().getId()); role.append(" "); role.append(wfTask.getActivityName()); role.append(" "); role.append(srcLocale); role.append(" "); role.append(trgLocale); if (isUserRole) { role.append(" ").append(userId); } return role.toString(); } private static Company getCompanyByName(String companyName) { try { return ServerProxy.getJobHandler().getCompany(companyName); } catch (Exception e) { return null; } } private void updateWorkflowTaskToDefault(WorkflowTask wfTask, String srcLocale, String trgLocale) { wfTask.setDisplayRoleName(WorkflowTask.DEFAULT_ROLE_NAME); wfTask.setRoleType(false); wfTask.setRolePreference(null); String[] roles = new String[1]; roles[0] = getRole(false, wfTask, srcLocale, trgLocale, null); wfTask.setRoles(roles); } /** * Offline download to get reviewers comments report, translations edit * report or offline translation kit. For offline translation kit * downloading, it will follow logged user's "Download Options" as default. * * @param p_accessToken * -- login user's token * @param p_taskId * -- task ID to offline download file for. * @param p_workOfflineFileType * -- 1 : Reviewer Comments Report or Translations Edit Report (this follows UI settings) * -- 2 : Offline Translation Kit * -- 3 : Translation Edit Report * -- 4 : Reviewer Comments Report * -- 5 : Reviewer Comments Report (Simplified) * -- 6 : Post Review QA Report * -- 7 : Translation Verification Report * -- 8 : Biligual Trados RTF * -- 9 : Trados 7 TTX * -- 10 : OmegaT * -- 11 : XLiff 1.2 * -- 12 : Xliff 2.0 * -- 13 : RTF List view * -- 14 : Reviewer Comments Report with Compact Tags * -- 15 : Reviewer Comments Report (Simplified) with Compact Tags *@param p_workofflineFileTypeOption * --1 : consolidate/split = split per file, include repeated segments = no (Default) * --2 : consolidate/split = consolidate (overrides preserve folder structure setting),include repeated segments = no * --3 : consolidate/split = split per wordcount of 2000, include repeated segments = no * --4 : consolidate/split = split per file, include repeated segments = yes * --5 : consolidate/split = consolidate (overrides preserve folder structure setting),include repeated segments = yes * --6 : consolidate/split = split per wordcount of 2000, include repeated segments = yes * @return -- JSON string. -- If fail, it is like * '{"getWorkOfflineFiles":"Corresponding message is here."}'; -- If * succeed, report returning is like * '{"taskId":3715,"targetLocale":"zh_CN","acceptorUserId":"yorkadmin","path":"http://10.10.215.21:8080/globalsight/DownloadReports/yorkadmin/TranslationsEditReport/20140219/ReviewersCommentsReport-(jobname_492637643)(337)-en_US_zh_CN-20140218 * 162543.xlsx"}'. -- offline translation kit returning is like * '{"taskId":3715,"targetLocale":"zh_CN","acceptorUserId":"yorkadmin","path":"http://10.10.215.21:8080/globalsight/DownloadOfflineKit/[CompanyName]/GlobalSight/CustomerDownload/[jobName_zh_CN.zip]"}' * . * @throws WebServiceException */ public String getWorkOfflineFiles(String p_accessToken, Long p_taskId, int p_workOfflineFileType, String p_workofflineFileTypeOption) throws WebServiceException { checkAccess(p_accessToken, GET_WORK_OFFLINE_FILES); AmbassadorHelper helper = new AmbassadorHelper(); return helper.getWorkOfflineFiles(p_accessToken, p_taskId, p_workOfflineFileType, p_workofflineFileTypeOption, true); } /** * Upload offline files to server. * * @param p_accessToken * -- login user's token * @param p_taskId * -- task ID to upload file to. * @param p_workOfflineFileType * -- 1 : For reports like "Reviewer Comments Report", "Simplified Reviewer Comments Report", * "Translations Edit Report", "Post Review QA Report" or "Translation Verification Report". * -- 2 : Offline Translation Kit * @param p_fileName * -- the upload file name * @param bytes * -- file contents in bytes * @return -- If succeed, return a "identifyKey" which is used to differ * this uploading, a sample is '{"identifyKey":"532689969","uploadWorkOfflineFiles":""}'; * -- If fail, no key, only return corresponding message, a sample is like '{"uploadWorkOfflineFiles":"Corresponding message is here."}'; * * @throws WebServiceException */ public String uploadWorkOfflineFiles(String p_accessToken, Long p_taskId, int p_workOfflineFileType, String p_fileName, byte[] bytes) throws WebServiceException { checkAccess(p_accessToken, UPLOAD_WORK_OFFLINE_FILES); AmbassadorHelper helper = new AmbassadorHelper(); return helper.uploadWorkOfflineFiles(p_accessToken, p_taskId, p_workOfflineFileType, p_fileName, bytes, true); } /** * Process offline file to update system. * * @param p_accessToken * -- login user's token * @param p_taskId * -- task ID to import file into. * @param p_identifyKey * -- identifyKey to help locate where the uploaded file is. * @param p_workOfflineFileType * -- 1 : For reports like "Reviewer Comments Report", "Simplified Reviewer Comments Report", * "Translations Edit Report", "Post Review QA Report" or "Translation Verification Report". * -- 2 : Offline Translation Kit * @return -- Empty if succeed; if fail, return corresponding message. * * @throws WebServiceException */ public String importWorkOfflineFiles(String p_accessToken, Long p_taskId, String p_identifyKey, int p_workOfflineFileType) throws WebServiceException { checkAccess(p_accessToken, IMPORT_WORK_OFFLINE_FILES); AmbassadorHelper helper = new AmbassadorHelper(); return helper.importWorkOfflineFiles(p_accessToken, p_taskId, p_identifyKey, p_workOfflineFileType, true); } /** * Get a link for in context review for specified task ID. User need not * logging in GlobalSight. * * @param p_accessToken * -- login user's token * @param p_taskId * -- task ID * @return A link like "http://10.10.215.20:8080/globalsight/ControlServlet?linkName=self&pageName=inctxrvED1&secret=E127B35E1A1C1B52C742353BBA176327D7F54956B373428134DE7252182EAA0D". * * @throws WebServiceException */ public String getInContextReviewLink(String p_accessToken, String p_taskId) throws WebServiceException { checkAccess(p_accessToken, GET_IN_CONTEXT_REVIEW_LINK); try { Assert.assertNotEmpty(p_accessToken, "Access token"); Assert.assertIsInteger(p_taskId); } catch (Exception e) { logger.error(e.getMessage(), e); return makeErrorJson(GET_IN_CONTEXT_REVIEW_LINK, e.getMessage()); } String loggingUserName = getUsernameFromSession(p_accessToken); String userId = UserUtil.getUserIdByName(loggingUserName); Task task = null; try { task = TaskHelper.getTask(Long.parseLong(p_taskId)); } catch (Exception e) { logger.error(e.getMessage(), e); String message = "Failed to get task object by taskId : " + p_taskId; return makeErrorJson(GET_IN_CONTEXT_REVIEW_LINK, message); } if (task == null) { return makeErrorJson(GET_IN_CONTEXT_REVIEW_LINK, "Can not get task by taskID."); } if (task.getState() == Task.STATE_COMPLETED) { return makeErrorJson(GET_IN_CONTEXT_REVIEW_LINK, "The current task has been in completed state."); } WebServicesLog.Start activityStart = null; try { Map<Object, Object> activityArgs = new HashMap<Object, Object>(); activityArgs.put("loggedUserName", loggingUserName); activityArgs.put("taskId", p_taskId); activityStart = WebServicesLog.start(Ambassador4Falcon.class, "getInContextReviewLink(p_accessToken, p_taskId)", activityArgs); User pm = task.getWorkflow().getJob().getProject().getProjectManager(); WorkflowTaskInstance wfTask = ServerProxy.getWorkflowServer().getWorkflowTaskInstance(userId, task.getId(), WorkflowConstants.TASK_ALL_STATES); task.setWorkflowTask(wfTask); List allAssignees = task.getAllAssignees(); if (allAssignees != null && allAssignees.size() > 0) { if (!allAssignees.contains(userId) && !userId.equalsIgnoreCase(pm.getUserId())) { String message = "'" + userId + "' is neither acceptor/available assignee of current task nor project manager."; logger.warn(message); return makeErrorJson(GET_IN_CONTEXT_REVIEW_LINK, message); } } StringBuffer link = new StringBuffer(); link.append(AmbassadorUtil.getCapLoginOrPublicUrl()); link.append("/ControlServlet?linkName=self&pageName=inctxrvED1&secret="); StringBuffer secret = new StringBuffer(); secret.append("taskId=").append(p_taskId.trim()).append("&nameField=").append(loggingUserName); link.append(AmbassadorUtil.encryptionString(secret.toString())); return link.toString(); } catch (Exception e) { logger.error(e.getMessage(), e); String message = "Failed to get In Context Review Link for taskId : " + p_taskId; return makeErrorJson(GET_IN_CONTEXT_REVIEW_LINK, message); } finally { if (activityStart != null) { activityStart.end(); } } } /** * Returns an json description containing projects information according by * current user * * This method will return projects information which are in charge by * current user. * * @param p_accessToken * * @return java.lang.String * @throws WebServiceException */ public String getAllProjectsByUser(String p_accessToken) throws WebServiceException { checkAccess(p_accessToken, GET_ALL_PROJECTS_BY_USER); // checkPermission(p_accessToken, Permission.GET_ALL_PROJECTS); List projects = null; try { String username = getUsernameFromSession(p_accessToken); User user = ServerProxy.getUserManager().getUserByName(username); projects = ServerProxy.getProjectHandler().getProjectInfosManagedByUser(user, Permission.GROUP_MODULE_GLOBALSIGHT); } catch (Exception e) { String message = "Unable to get all projects infos managed by user"; logger.error(message, e); message = makeErrorJson("getAllProjectsByUser", message); throw new WebServiceException(message); } JSONArray array = new JSONArray(); Iterator it = projects.iterator(); try { while (it.hasNext()) { JSONObject json = new JSONObject(); ProjectInfo pi = (ProjectInfo) it.next(); json.put("projectId", pi.getProjectId()); json.put("projectName", pi.getName()); json.put("companyId", pi.getCompanyId()); json.put("companyName", CompanyWrapper.getCompanyNameById(pi.getCompanyId())); if (pi.getDescription() == null || pi.getDescription().length() < 1) { json.put("description", "N/A"); } else { json.put("description", pi.getDescription()); } array.put(json); } } catch (JSONException e) { e.printStackTrace(); } return array.toString(); } /** * Get activities current logged user is in charge of. * * @param p_accessToken * -- login user's token * @param p_projectIds * -- project IDs, comma separated. A sample is "12,13". Can be * null. * @param p_taskState * -- taskState, can be null. Available values are "8" or "3"("8" * means "in progress","3" means "available"). * * @return string in JSON * @throws WebServiceException */ public String getActivityList(String p_accessToken, String p_projectIds, String p_taskState) throws WebServiceException { checkAccess(p_accessToken, GET_ACTIVITY_LIST); try { if (StringUtils.isNotBlank(p_taskState)) { Assert.assertIsInteger(p_taskState); } if (StringUtils.isNotBlank(p_projectIds)) { if (p_projectIds.contains(",")) { String[] projectIds = p_projectIds.split(","); for (String projectId : projectIds) { Assert.assertIsInteger(projectId); } } else { Assert.assertIsInteger(p_projectIds); } } } catch (Exception e) { logger.error(e.getMessage(), e); return makeErrorJson(GET_ACTIVITY_LIST, e.getMessage()); } if (StringUtils.isNotBlank(p_taskState)) { if (Integer.parseInt(p_taskState) != 3 && Integer.parseInt(p_taskState) != 8) { return makeErrorJson(GET_ACTIVITY_LIST, "Task state can only be 3 (available) and 8 (in progress). The input state is " + p_taskState); } } try { List tasks = null; String username = getUsernameFromSession(p_accessToken); User user = ServerProxy.getUserManager().getUserByName(username); if (StringUtils.isBlank(p_taskState)) { tasks = ServerProxy.getTaskManager().getTasks(user.getUserId(), -10); } else { tasks = ServerProxy.getTaskManager().getTasks(user.getUserId(), Integer.parseInt(p_taskState)); } List<Long> projectIdList = new ArrayList<Long>(); if (StringUtils.isNotBlank(p_projectIds)) { String[] projectIds = p_projectIds.split(","); for (String projectId : projectIds) { projectIdList.add(Long.parseLong(projectId)); } } JSONArray arrayOut = new JSONArray(); Map<String, List<Task>> map = new HashMap<String, List<Task>>(); List<Task> list = null; for (int i = 0; i < tasks.size(); i++) { Task task = (Task) tasks.get(i); if (projectIdList.size() > 0 && !projectIdList.contains(task.getWorkflow().getJob().getProjectId())) { continue; } if (StringUtils.isBlank(p_taskState)) { if (task.getState() != 3 && task.getState() != 8) { continue; } } if (map.containsKey(task.getJobId() + "," + task.getJobName())) { list = map.get(task.getJobId() + "," + task.getJobName()); list.add(task); } else { list = new ArrayList<Task>(); list.add(task); } map.put(task.getJobId() + "," + task.getJobName(), list); } for (Entry<String, List<Task>> entry : map.entrySet()) { String key = entry.getKey(); List<Task> taskList = entry.getValue(); JSONObject jsonOut = new JSONObject(); String[] keyArr = key.split(","); jsonOut.put("jobID", keyArr[0]); jsonOut.put("jobName", keyArr[1]); JSONArray arrayIn = new JSONArray(); for (Task tk : taskList) { JSONObject jsonIn = new JSONObject(); jsonIn.put("targetLanguage", tk.getTargetLocale()); jsonIn.put("taskID", tk.getId()); jsonIn.put("taskState", (tk.getState() == 3 ? "AVAILABLE" : "IN PROGRESS")); arrayIn.put(jsonIn); } jsonOut.put("workflow", arrayIn); arrayOut.put(jsonOut); } return arrayOut.toString(); } catch (Exception e) { String message = "Unable to get all projects infos managed by user"; logger.error(message, e); message = makeErrorJson(GET_ACTIVITY_LIST, message); throw new WebServiceException(message); } } /////////////////////////////////////////////////////////////////////////// //// COMMON PRIVATE METHODS /////////////////////////////////////////////////////////////////////////// private static Locale getUILocale(String p_accessToken) throws UserManagerException, RemoteException, GeneralException { User user = ServerProxy.getUserManager().getUserByName(getUsernameFromSession(p_accessToken)); return new Locale(user.getDefaultUILocale()); } /** * Change array to string comma separated. * * @return String like "string1,string2,string3". */ private static String arrayToString(String[] array) { StringBuilder buffer = new StringBuilder(); int counter = 0; for (String str : array) { if (counter > 0) { buffer.append(","); } counter++; buffer.append(str); } return buffer.toString(); } private static List<String> stringToList(String string) { List<String> result = new ArrayList<String>(); String[] tokens = Strings.split(string, ","); for (int i = 0; i < tokens.length; i++) { String token = tokens[i].trim(); if (StringUtil.isNotEmpty(token)) { result.add(token); } } return result; } private static String[] stringToArray(String string) { // get list first as stringToList has "NotEmpty" check. List<String> list = stringToList(string); return listToArray(list); } private static String[] listToArray(List<String> list) { String[] array = new String[list.size()]; for (int i = 0; i < list.size(); i++) { array[i] = list.get(i); } return array; } }