View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations under the License.
17   */
18  package org.apache.shindig.social.opensocial.service;
19  
20  import org.apache.shindig.auth.SecurityToken;
21  import org.apache.shindig.social.opensocial.spi.DataCollection;
22  import org.apache.shindig.social.opensocial.spi.RestfulCollection;
23  
24  import com.google.common.collect.ImmutableMap;
25  import com.google.common.collect.Maps;
26  
27  import java.io.IOException;
28  import java.io.PrintWriter;
29  import java.util.logging.Logger;
30  import javax.servlet.ServletException;
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpServletResponse;
33  
34  public class DataServiceServlet extends ApiServlet {
35  
36    protected static final String FORMAT_PARAM = "format";
37    protected static final String ATOM_FORMAT = "atom";
38    protected static final String XML_FORMAT = "xml";
39  
40    public static final String PEOPLE_ROUTE = "people";
41    public static final String ACTIVITY_ROUTE = "activities";
42    public static final String APPDATA_ROUTE = "appdata";
43  
44    public static final String CONTENT_TYPE = "CONTENT_TYPE";
45  
46    private static final Logger logger = Logger.getLogger(
47        "org.apache.shindig.social.opensocial.spi");
48  
49    @Override
50    protected void doGet(HttpServletRequest servletRequest,
51        HttpServletResponse servletResponse)
52        throws ServletException, IOException {
53      doPost(servletRequest, servletResponse);
54    }
55  
56    @Override
57    protected void doPut(HttpServletRequest servletRequest,
58        HttpServletResponse servletResponse)
59        throws ServletException, IOException {
60      doPost(servletRequest, servletResponse);
61    }
62  
63    @Override
64    protected void doDelete(HttpServletRequest servletRequest,
65        HttpServletResponse servletResponse)
66        throws ServletException, IOException {
67      doPost(servletRequest, servletResponse);
68    }
69  
70    @Override
71    protected void doPost(HttpServletRequest servletRequest,
72        HttpServletResponse servletResponse)
73        throws ServletException, IOException {
74      logger.finest("Handling restful request for " + servletRequest.getPathInfo());
75  
76      setCharacterEncodings(servletRequest, servletResponse);
77  
78      SecurityToken token = getSecurityToken(servletRequest);
79      if (token == null) {
80        sendSecurityError(servletResponse);
81        return;
82      }
83  
84      BeanConverter converter = getConverterForRequest(servletRequest);
85  
86      handleSingleRequest(servletRequest, servletResponse, token, converter);
87    }
88  
89    @Override
90    protected void sendError(HttpServletResponse servletResponse, ResponseItem responseItem)
91        throws IOException {
92      servletResponse.sendError(responseItem.getError().getHttpErrorCode(),
93          responseItem.getErrorMessage());
94    }
95  
96    /***
97     * Handler for non-batch requests.
98     */
99    private void handleSingleRequest(HttpServletRequest servletRequest,
100       HttpServletResponse servletResponse, SecurityToken token,
101       BeanConverter converter) throws IOException {
102     RestfulRequestItem requestItem = new RestfulRequestItem(servletRequest, token, converter);
103     ResponseItem responseItem = getResponseItem(handleRequestItem(requestItem, servletRequest));
104 
105     servletResponse.setContentType(converter.getContentType());
106     if (responseItem.getError() == null) {
107       PrintWriter writer = servletResponse.getWriter();
108       Object response = responseItem.getResponse();
109       // TODO: ugliness resulting from not using RestfulItem
110       if (!(response instanceof DataCollection) && !(response instanceof RestfulCollection)) {
111         response = ImmutableMap.of("entry", response);
112       }
113 
114       writer.write(converter.convertToString(response));
115     } else {
116       sendError(servletResponse, responseItem);
117     }
118   }
119 
120 
121   BeanConverter getConverterForRequest(HttpServletRequest servletRequest) {
122     String formatString = null;
123     BeanConverter converter = null;
124     String contentType = null;
125 
126     try {
127       formatString = servletRequest.getParameter(FORMAT_PARAM);
128     } catch (Throwable t) {
129       // this happens while testing
130       logger.fine("Unexpected error : format param is null " + t.toString());
131     }
132     try {
133       contentType = servletRequest.getHeader(CONTENT_TYPE);
134     } catch (Throwable t) {
135       //this happens while testing
136       logger.fine("Unexpected error : content type is null " + t.toString());
137     }
138 
139     if (contentType != null) {
140       if (contentType.equals("application/json")) {
141         converter = jsonConverter;
142       } else if (contentType.equals("application/atom+xml")) {
143         converter = atomConverter;
144       } else if (contentType.equals("application/xml")) {
145         converter = xmlConverter;
146       } else if (formatString == null) {
147         // takes care of cases where content!= null but is ""
148         converter = jsonConverter;
149       }
150     } else if (formatString != null) {
151       if (formatString.equals(ATOM_FORMAT)) {
152         converter = atomConverter;
153       } else if (formatString.equals(XML_FORMAT)) {
154         converter = xmlConverter;
155       } else {
156         converter = jsonConverter;
157       }
158     } else {
159       converter = jsonConverter;
160     }
161     return converter;
162   }
163 }