/*
* Copyright (c) 2009 Lockheed Martin Corporation
*
* 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 org.eurekastreams.server.service.restlets;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eurekastreams.server.domain.Job;
import org.eurekastreams.server.domain.Person;
import org.eurekastreams.server.persistence.JobMapper;
import org.restlet.data.Request;
import org.restlet.data.Status;
import org.restlet.resource.ResourceException;
/**
* REST abstract endpoint class for an job resource.
*/
public abstract class JobsResource extends WritableResource
{
/**
* Logger.
*/
private Log log = LogFactory.getLog(JobsResource.class);
/**
* Mapper to retrieve a Job.
*/
private JobMapper jobMapper;
/**
* The key used in the JSON string.
*/
protected static final String JOBS_KEY = "jobs";
/**
* The key used in the JSON string.
*/
protected static final String JOB_ID_KEY = "id";
/**
* The company name key used in the JSON string.
*/
protected static final String COMPANY_NAME_KEY = "companyname";
/**
* The industry key used in the JSON string.
*/
protected static final String INDUSTRY_KEY = "industry";
/**
* The title key used in the JSON string.
*/
protected static final String TITLE_KEY = "title";
/**
* The date from key used in the JSON string.
*/
protected static final String DATE_FROM_KEY = "datefrom";
/**
* The date from key used in the JSON string.
*/
protected static final String DATE_FROM_YEAR_KEY = "datefromyear";
/**
* The date from key used in the JSON string.
*/
protected static final String DATE_FROM_MONTH_KEY = "datefrommonth";
/**
* The date to key used in the JSON string.
*/
protected static final String DATE_TO_KEY = "dateto";
/**
* The date to key used in the JSON string.
*/
protected static final String DATE_TO_YEAR_KEY = "datetoyear";
/**
* The date to key used in the JSON string.
*/
protected static final String DATE_TO_MONTH_KEY = "datetomonth";
/**
* The title key used in the JSON string.
*/
protected static final String DESCRIPTION_KEY = "description";
/** for extracting strings from Dates. */
private DateFormat yearExtractor = new SimpleDateFormat("yyyy");
/** for extracting strings from Dates. */
private DateFormat monthExtractor = new SimpleDateFormat("MM");
/**
/**
* Initialize parameters from the request object.
* the context of the request
* @param request
* the client's request
*/
protected abstract void initParams(final Request request);
/**
*
* The Job Mapper. Used by tests.
*
* @param inJobMapper
* mapper.
*/
public void setJobMapper(final JobMapper inJobMapper)
{
jobMapper = inJobMapper;
}
/**
* @return the jobMapper
*/
protected JobMapper getJobMapper()
{
return jobMapper;
}
/**
* Converts a JSONObject into a job object.
* @param inJsonJob - json representation of a job to try and parse.
* @param inPerson - person to whom the job belongs
* @return - Job object.
* @throws ParseException - if a dateformat parsing error occurs.
*/
protected Job convertJSONObjectToJob(final JSONObject inJsonJob,
final Person inPerson) throws ParseException
{
DateFormat df = new SimpleDateFormat("MM/yyyy");
String companyName = inJsonJob.getString(COMPANY_NAME_KEY);
String industry = inJsonJob.getString(INDUSTRY_KEY);
String title = inJsonJob.getString(TITLE_KEY);
String dateFromString =
inJsonJob.getString(DATE_FROM_MONTH_KEY) + "/" + inJsonJob.getString(DATE_FROM_YEAR_KEY);
Date dateFrom = df.parse(dateFromString);
Date dateTo = null;
if (!inJsonJob.getString(DATE_TO_YEAR_KEY).equals(""))
{
String dateToString =
inJsonJob.getString(DATE_TO_MONTH_KEY) + "/" + inJsonJob.getString(DATE_TO_YEAR_KEY);
dateTo = df.parse(dateToString);
}
String description = inJsonJob.getString(DESCRIPTION_KEY);
Job job = new Job(inPerson, companyName, industry, title, dateFrom, dateTo, description);
return job;
}
/**
* Convert the passed in Job object to JSON.
* @param inJob - job object to convert to JSON.
* @return JSON representation of the passed in Job object.
*/
protected JSONObject convertJobToJSON(final Job inJob)
{
JSONObject jsonJobObject = new JSONObject();
jsonJobObject.put(JOB_ID_KEY, inJob.getId());
jsonJobObject.put(COMPANY_NAME_KEY, inJob.getCompanyName());
jsonJobObject.put(INDUSTRY_KEY, inJob.getIndustry());
jsonJobObject.put(TITLE_KEY, inJob.getTitle());
Date dateFrom = inJob.getDateFrom();
String year = getYear(dateFrom);
String month = getMonth(dateFrom);
jsonJobObject.put(DATE_FROM_YEAR_KEY, year);
jsonJobObject.put(DATE_FROM_MONTH_KEY, month);
// if null, the string is empty (presumably this is Present Date)
Date dateTo = inJob.getDateTo();
year = getYear(dateTo);
month = getMonth(dateTo);
jsonJobObject.put(DATE_TO_YEAR_KEY, year);
jsonJobObject.put(DATE_TO_MONTH_KEY, month);
jsonJobObject.put(DESCRIPTION_KEY, inJob.getDescription());
return jsonJobObject;
}
/**
*
* @param input the date
* @return 4-digit year string
*/
protected String getYear(final Date input)
{
String result = (input == null ? "" : yearExtractor.format(input));
return result;
}
/**
*
* @param input the date
* @return 2-digit month string
*/
protected String getMonth(final Date input)
{
String result = (input == null ? "" : monthExtractor.format(input));
return result;
}
/**
* Validates the Enrollment object and throws an exception if it does not validate.
* @param inJsonObject - json object containing the Enrollment to be persisted.
* @throws ParseException - occurs if the JSON cannot be parsed correctly.
* @throws ResourceException - thrown if the Enrollment is invalid.
*/
protected void validateJobHistory(final JSONObject inJsonObject) throws ParseException, ResourceException
{
JSONObject validationErrors = new JSONObject();
JSONArray validationErrorsList = new JSONArray();
boolean valid = true;
if (inJsonObject.getString(COMPANY_NAME_KEY).length() == 0)
{
valid = false;
validationErrorsList.add("Company Name is required.");
}
if (inJsonObject.getString(INDUSTRY_KEY).length() == 0)
{
valid = false;
validationErrorsList.add("Industry is required.");
}
if (inJsonObject.getString(TITLE_KEY).length() == 0)
{
valid = false;
validationErrorsList.add("Job Title is required.");
}
if (inJsonObject.getString(DESCRIPTION_KEY).length() == 0)
{
valid = false;
validationErrorsList.add("Job Description is required.");
}
if (inJsonObject.getString(DATE_FROM_MONTH_KEY).length() == 0
|| inJsonObject.getString(DATE_FROM_YEAR_KEY).length() == 0)
{
valid = false;
validationErrorsList.add("Job Start Date is required.");
}
try
{
//testing for valid date. A date is not required.
String dateFromYear = inJsonObject.getString(DATE_FROM_YEAR_KEY);
String dateFromMonth = inJsonObject.getString(DATE_FROM_MONTH_KEY);
String dateToYear = inJsonObject.getString(DATE_FROM_YEAR_KEY);
String dateToMonth = inJsonObject.getString(DATE_FROM_MONTH_KEY);
if (!(testDate(dateFromMonth, dateFromYear)
&& testDate(dateToMonth, dateToYear)))
{
valid = false;
validationErrorsList.add("Job Time Period is invalid, "
+ "please verify that the dates are correct and in chronological order.");
}
}
catch (ParseException pex)
{
//Not a parseable date string.
valid = false;
validationErrorsList.add("Job Time Period is invalid, "
+ "please verify that the dates are correct and in chronological order.");
}
if (!valid)
{
log.debug("Job Resource validation: invalid " + validationErrorsList.toString());
validationErrors.put(VALIDATION_ERRORS_KEY, validationErrorsList);
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, validationErrors.toString());
}
}
/**
* Helper method for validating the date formatting.
* @param dateMonth - string month to test validation.
* @param dateYear - string year to test validation.
* @return - false if the validation doesn't succeed.
* @throws ParseException - if a date parsing exception occurs.
*/
private boolean testDate(final String dateMonth, final String dateYear) throws ParseException
{
boolean validDate = true;
if (dateMonth.length() > 0 && dateYear.length() > 0)
{
//Incorrect number of characters in the date.
if (!Pattern.matches("[0-9]{4}", dateYear))
{
validDate = false;
}
DateFormat df = new SimpleDateFormat("MM/yyyy");
Date testDate = df.parse(dateMonth + "/" + dateYear);
}
return validDate;
}
}