You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2009/06/28 17:33:25 UTC
svn commit: r789112 - in
/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort:
ICalConverter.java ICalWorker.java
Author: adrianc
Date: Sun Jun 28 15:33:24 2009
New Revision: 789112
URL: http://svn.apache.org/viewvc?rev=789112&view=rev
Log:
More iCalendar work - improved HTTP responses.
Modified:
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java
Modified: ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java?rev=789112&r1=789111&r2=789112&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java (original)
+++ ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java Sun Jun 28 15:33:24 2009
@@ -62,6 +62,7 @@
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.service.calendar.TemporalExpression;
import org.ofbiz.service.calendar.TemporalExpressionWorker;
+import static org.ofbiz.workeffort.workeffort.ICalWorker.ResponseProperties;
/** iCalendar converter class. This class uses the <a href="http://ical4j.sourceforge.net/index.html">
* iCal4J</a> library.
@@ -115,7 +116,7 @@
return organizer;
}
- protected static void createWorkEffort(Component component, Map<String, Object> context) {
+ protected static ResponseProperties createWorkEffort(Component component, Map<String, Object> context) {
Map<String, Object> serviceMap = FastMap.newInstance();
setWorkEffortServiceMap(component, serviceMap);
serviceMap.put("workEffortTypeId", "VTODO".equals(component.getName()) ? "TASK" : "EVENT");
@@ -124,6 +125,9 @@
serviceMap.put("roleTypeId", "CAL_OWNER");
serviceMap.put("statusId", "PRTYASGN_ASSIGNED");
Map<String, Object> serviceResult = invokeService("createWorkEffortAndPartyAssign", serviceMap, context);
+ if (ServiceUtil.isError(serviceResult)) {
+ return ICalWorker.createPartialContentResponse(ServiceUtil.getErrorMessage(serviceResult));
+ }
String workEffortId = (String) serviceResult.get("workEffortId");
if (workEffortId != null) {
replaceProperty(component.getProperties(), toXProperty(workEffortIdXPropName, workEffortId));
@@ -134,10 +138,11 @@
serviceMap.put("fromDate", new Timestamp(System.currentTimeMillis()));
serviceResult = invokeService("createWorkEffortAssoc", serviceMap, context);
if (ServiceUtil.isError(serviceResult)) {
- return;
+ return ICalWorker.createPartialContentResponse(ServiceUtil.getErrorMessage(serviceResult));
}
storePartyAssignments(workEffortId, component, context);
}
+ return null;
}
protected static String fromClazz(PropertyList propertyList) {
@@ -348,22 +353,25 @@
* if <code>workEffortId</code> is invalid.
* @throws GenericEntityException
*/
- public static String getICalendar(String workEffortId, Map<String, Object> context) throws GenericEntityException {
+ public static ResponseProperties getICalendar(String workEffortId, Map<String, Object> context) throws GenericEntityException {
GenericDelegator delegator = (GenericDelegator) context.get("delegator");
GenericValue publishProperties = delegator.findOne("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId), false);
if (!isCalendarPublished(publishProperties)) {
Debug.logInfo("WorkEffort calendar is not published: " + workEffortId, module);
- return null;
+ return ICalWorker.createNotFoundResponse(null);
}
if (!"WES_PUBLIC".equals(publishProperties.get("scopeEnumId")) && !hasPermission(workEffortId, "VIEW", context)) {
- return null;
+ return ICalWorker.createNotFoundResponse(null);
}
Calendar calendar = makeCalendar(publishProperties, context);
ComponentList components = calendar.getComponents();
List<GenericValue> workEfforts = getRelatedWorkEfforts(publishProperties, context);
if (workEfforts != null) {
for (GenericValue workEffort : workEfforts) {
- toCalendarComponent(components, workEffort, context);
+ ResponseProperties responseProps = toCalendarComponent(components, workEffort, context);
+ if (responseProps != null) {
+ return responseProps;
+ }
}
}
if (Debug.verboseOn()) {
@@ -374,7 +382,7 @@
Debug.logVerbose("iCalendar fails validation: " + e, module);
}
}
- return calendar.toString();
+ return ICalWorker.createOkResponse(calendar.toString());
}
protected static void getPartyUrl(Property property, GenericValue partyAssign, Map<String, Object> context) {
@@ -638,7 +646,7 @@
* @throws GenericServiceException
*/
@SuppressWarnings("unchecked")
- public static void storeCalendar(InputStream is, Map<String, Object> context) throws IOException, ParserException, GenericEntityException, GenericServiceException {
+ public static ResponseProperties storeCalendar(InputStream is, Map<String, Object> context) throws IOException, ParserException, GenericEntityException, GenericServiceException {
CalendarBuilder builder = new CalendarBuilder();
Calendar calendar = null;
try {
@@ -661,65 +669,74 @@
if (!workEffortId.equals(context.get("workEffortId"))) {
Debug.logWarning("Spoof attempt: received calendar workEffortId " + workEffortId +
" on URL workEffortId " + context.get("workEffortId"), module);
- return;
+ return ICalWorker.createForbiddenResponse(null);
}
GenericDelegator delegator = (GenericDelegator) context.get("delegator");
GenericValue publishProperties = delegator.findOne("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId), false);
if (!isCalendarPublished(publishProperties)) {
Debug.logInfo("WorkEffort calendar is not published: " + workEffortId, module);
- return;
+ return ICalWorker.createNotFoundResponse(null);
}
if (!hasPermission(workEffortId, "UPDATE", context)) {
- return;
+ return ICalWorker.createNotAuthorizedResponse(null);
}
boolean hasCreatePermission = hasPermission(workEffortId, "CREATE", context);
List<GenericValue> workEfforts = getRelatedWorkEfforts(publishProperties, context);
- if (workEfforts == null || workEfforts.size() == 0) {
- return;
- }
- // Security issue: make sure only related work efforts get updated
- Set validWorkEfforts = FastSet.newInstance();
- for (GenericValue workEffort : workEfforts) {
- validWorkEfforts.add(workEffort.getString("workEffortId"));
- }
- List<Component> components = calendar.getComponents();
- for (Component component : components) {
- if (Component.VEVENT.equals(component.getName()) || Component.VTODO.equals(component.getName())) {
- workEffortId = fromXProperty(component.getProperties(), workEffortIdXPropName);
- if (workEffortId == null) {
- Property uid = component.getProperty(Uid.UID);
- if (uid != null) {
- GenericValue workEffort = EntityUtil.getFirst(delegator.findByAnd("WorkEffort", UtilMisc.toMap("universalId", uid.getValue())));
- if (workEffort != null) {
- workEffortId = workEffort.getString("workEffortId");
+ if (workEfforts != null && workEfforts.size() > 0) {
+ // Security issue: make sure only related work efforts get updated
+ Set validWorkEfforts = FastSet.newInstance();
+ for (GenericValue workEffort : workEfforts) {
+ validWorkEfforts.add(workEffort.getString("workEffortId"));
+ }
+ List<Component> components = calendar.getComponents();
+ ResponseProperties responseProps = null;
+ for (Component component : components) {
+ if (Component.VEVENT.equals(component.getName()) || Component.VTODO.equals(component.getName())) {
+ workEffortId = fromXProperty(component.getProperties(), workEffortIdXPropName);
+ if (workEffortId == null) {
+ Property uid = component.getProperty(Uid.UID);
+ if (uid != null) {
+ GenericValue workEffort = EntityUtil.getFirst(delegator.findByAnd("WorkEffort", UtilMisc.toMap("universalId", uid.getValue())));
+ if (workEffort != null) {
+ workEffortId = workEffort.getString("workEffortId");
+ }
}
}
- }
- if (workEffortId != null) {
- if (validWorkEfforts.contains(workEffortId)) {
- replaceProperty(component.getProperties(), toXProperty(workEffortIdXPropName, workEffortId));
- storeWorkEffort(component, context);
- } else {
- Debug.logWarning("Spoof attempt: unrelated workEffortId " + workEffortId +
- " on URL workEffortId " + context.get("workEffortId"), module);
- continue;
+ if (workEffortId != null) {
+ if (validWorkEfforts.contains(workEffortId)) {
+ replaceProperty(component.getProperties(), toXProperty(workEffortIdXPropName, workEffortId));
+ responseProps = storeWorkEffort(component, context);
+ } else {
+ Debug.logWarning("Spoof attempt: unrelated workEffortId " + workEffortId +
+ " on URL workEffortId " + context.get("workEffortId"), module);
+ responseProps = ICalWorker.createForbiddenResponse(null);
+ }
+ } else if (hasCreatePermission) {
+ responseProps = createWorkEffort(component, context);
+ }
+ if (responseProps != null) {
+ return responseProps;
}
- } else if (hasCreatePermission) {
- createWorkEffort(component, context);
}
}
}
Map<String, ? extends Object> serviceMap = UtilMisc.toMap("workEffortId", context.get("workEffortId"), "icalData", calendar.toString());
GenericValue iCalData = publishProperties.getRelatedOne("WorkEffortIcalData");
+ Map<String, Object> serviceResult = null;
if (iCalData == null) {
- invokeService("createWorkEffortICalData", serviceMap, context);
+ serviceResult = invokeService("createWorkEffortICalData", serviceMap, context);
} else {
- invokeService("updateWorkEffortICalData", serviceMap, context);
+ serviceResult = invokeService("updateWorkEffortICalData", serviceMap, context);
+ }
+ if (ServiceUtil.isError(serviceResult)) {
+ return ICalWorker.createPartialContentResponse(ServiceUtil.getErrorMessage(serviceResult));
}
+ return ICalWorker.createOkResponse(null);
}
@SuppressWarnings("unchecked")
- protected static void storePartyAssignments(String workEffortId, Component component, Map<String, Object> context) {
+ protected static ResponseProperties storePartyAssignments(String workEffortId, Component component, Map<String, Object> context) {
+ ResponseProperties responseProps = null;
Map<String, Object> serviceMap = FastMap.newInstance();
List<Property> partyList = FastList.newInstance();
partyList.addAll(component.getProperties("ATTENDEE"));
@@ -755,30 +772,33 @@
invokeService("assignPartyToWorkEffort", serviceMap, context);
}
} catch (GenericEntityException e) {
+ responseProps = ICalWorker.createPartialContentResponse(e.getMessage());
+ break;
}
}
+ return responseProps;
}
- protected static void storeWorkEffort(Component component, Map<String, Object> context) throws GenericEntityException, GenericServiceException {
+ protected static ResponseProperties storeWorkEffort(Component component, Map<String, Object> context) throws GenericEntityException, GenericServiceException {
PropertyList propertyList = component.getProperties();
String workEffortId = fromXProperty(propertyList, workEffortIdXPropName);
GenericDelegator delegator = (GenericDelegator) context.get("delegator");
GenericValue workEffort = delegator.findOne("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId), false);
if (workEffort == null) {
- return;
+ return ICalWorker.createNotFoundResponse(null);
}
if (!hasPermission(workEffortId, "UPDATE", context)) {
- return;
+ return ICalWorker.createNotAuthorizedResponse(null);
}
Map<String, Object> serviceMap = FastMap.newInstance();
serviceMap.put("workEffortId", workEffortId);
setWorkEffortServiceMap(component, serviceMap);
invokeService("updateWorkEffort", serviceMap, context);
- storePartyAssignments(workEffortId, component, context);
+ return storePartyAssignments(workEffortId, component, context);
}
@SuppressWarnings("unchecked")
- protected static void toCalendarComponent(ComponentList components, GenericValue workEffort, Map<String, Object> context) throws GenericEntityException {
+ protected static ResponseProperties toCalendarComponent(ComponentList components, GenericValue workEffort, Map<String, Object> context) throws GenericEntityException {
GenericDelegator delegator = workEffort.getDelegator();
String workEffortId = workEffort.getString("workEffortId");
String workEffortUid = workEffort.getString("universalId");
@@ -795,7 +815,7 @@
} else if ("EVENT".equals(workEffortTypeId) || (typeValue != null && "EVENT".equals(typeValue.get("parentTypeId")))){
resultList = components.getComponents("VEVENT");
} else {
- return;
+ return null;
}
Iterator<Component> i = resultList.iterator();
while (i.hasNext()) {
@@ -872,6 +892,7 @@
Debug.logVerbose(e, "iCalendar component fails validation: ", module);
}
}
+ return null;
}
protected static Clazz toClazz(String javaObj) {
Modified: ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java?rev=789112&r1=789111&r2=789112&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java (original)
+++ ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java Sun Jun 28 15:33:24 2009
@@ -61,8 +61,18 @@
* delegates the calendar conversion tasks to <code>ICalConverter</code>.
*/
public class ICalWorker {
+
public static final String module = ICalWorker.class.getName();
-
+
+ public static class ResponseProperties {
+ public final int statusCode;
+ public final String statusMessage;
+ public ResponseProperties(int statusCode, String statusMessage) {
+ this.statusCode = statusCode;
+ this.statusMessage = statusMessage;
+ }
+ }
+
@SuppressWarnings("unchecked")
protected static Map<String, Object> createConversionContext(HttpServletRequest request) {
Map<String, Object> context = FastMap.newInstance();
@@ -76,6 +86,26 @@
return context;
}
+ public static ResponseProperties createForbiddenResponse(String statusMessage) {
+ return new ResponseProperties(HttpServletResponse.SC_FORBIDDEN, statusMessage);
+ }
+
+ public static ResponseProperties createNotAuthorizedResponse(String statusMessage) {
+ return new ResponseProperties(HttpServletResponse.SC_UNAUTHORIZED, statusMessage);
+ }
+
+ public static ResponseProperties createNotFoundResponse(String statusMessage) {
+ return new ResponseProperties(HttpServletResponse.SC_NOT_FOUND, statusMessage);
+ }
+
+ public static ResponseProperties createOkResponse(String statusMessage) {
+ return new ResponseProperties(HttpServletResponse.SC_OK, statusMessage);
+ }
+
+ public static ResponseProperties createPartialContentResponse(String statusMessage) {
+ return new ResponseProperties(HttpServletResponse.SC_PARTIAL_CONTENT, statusMessage);
+ }
+
protected static Writer getWriter(HttpServletResponse response, ServletContext context) throws IOException {
Writer writer = null;
if (UtilJ2eeCompat.useOutputStreamNotWriter(context)) {
@@ -96,22 +126,18 @@
return;
}
Debug.logInfo("[handleGetRequest] workEffortId = " + workEffortId, module);
+ ResponseProperties responseProps = null;
try {
- String calendar = ICalConverter.getICalendar(workEffortId, createConversionContext(request));
- if (calendar == null) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
- response.setContentType("text/calendar");
- response.setStatus(HttpServletResponse.SC_OK);
- Writer writer = getWriter(response, context);
- writer.write(calendar);
- writer.close();
+ responseProps = ICalConverter.getICalendar(workEffortId, createConversionContext(request));
} catch (Exception e) {
Debug.logError(e, "[handleGetRequest] Error while sending calendar: ", module);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
+ if (responseProps.statusCode == HttpServletResponse.SC_OK) {
+ response.setContentType("text/calendar");
+ }
+ writeResponse(responseProps, response, context);
}
public static void handlePropFindRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException, IOException {
@@ -125,9 +151,10 @@
Debug.logInfo("[handlePropFindRequest] workEffortId = " + workEffortId, module);
try {
Document requestDocument = WebDavUtil.getDocumentFromRequest(request);
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- UtilXml.writeXmlDocument(os, requestDocument, "UTF-8", true, true);
+ ByteArrayOutputStream os = null;
if (Debug.verboseOn()) {
+ os = new ByteArrayOutputStream();
+ UtilXml.writeXmlDocument(os, requestDocument, "UTF-8", true, true);
Debug.logVerbose("[handlePropFindRequest] PROPFIND body:\r\n" + os.toString(), module);
}
PropFindHelper helper = new PropFindHelper(requestDocument);
@@ -162,9 +189,9 @@
Element rootElement = helper.createMultiStatusElement();
rootElement.appendChild(responseElement);
responseDocument.appendChild(rootElement);
- os = new ByteArrayOutputStream();
- UtilXml.writeXmlDocument(os, responseDocument, "UTF-8", true, true);
if (Debug.verboseOn()) {
+ os = new ByteArrayOutputStream();
+ UtilXml.writeXmlDocument(os, responseDocument, "UTF-8", true, true);
Debug.logVerbose("[handlePropFindRequest] PROPFIND response:\r\n" + os.toString(), module);
}
ResponseHelper.prepareResponse(response, 207, "Multi-Status");
@@ -196,14 +223,15 @@
return;
}
Debug.logInfo("[handlePutRequest] workEffortId = " + workEffortId, module);
+ ResponseProperties responseProps = null;
try {
- ICalConverter.storeCalendar(request.getInputStream(), createConversionContext(request));
+ responseProps = ICalConverter.storeCalendar(request.getInputStream(), createConversionContext(request));
} catch (Exception e) {
Debug.logError(e, "[handlePutRequest] Error while updating calendar: ", module);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
- response.setStatus(HttpServletResponse.SC_OK);
+ writeResponse(responseProps, response, context);
}
protected static void logInUser(HttpServletRequest request, HttpServletResponse response) throws GenericServiceException, GenericEntityException {
@@ -255,4 +283,22 @@
Debug.logError(e, "Error while logging in user: ", module);
}
}
+
+ protected static void writeResponse(ResponseProperties responseProps, HttpServletResponse response, ServletContext context) throws IOException {
+ if (Debug.verboseOn()) {
+ Debug.logVerbose("Returning response: code = " + responseProps.statusCode +
+ ", message = " + responseProps.statusMessage, module);
+ }
+ response.setStatus(responseProps.statusCode);
+ if (responseProps.statusMessage != null) {
+ Writer writer = getWriter(response, context);
+ try {
+ writer.write(responseProps.statusMessage);
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ writer.close();
+ }
+ }
+ }
}