KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > contineo > apis > rest > RestAPI


1 /* License: GNU General Public License (GPL) version 2 from June 1991; but not any newer version!
2  */

3 package org.contineo.apis.rest;
4
5 import java.io.IOException JavaDoc;
6
7 import javax.servlet.ServletException JavaDoc;
8 import javax.servlet.http.HttpServlet JavaDoc;
9 import javax.servlet.http.HttpServletRequest JavaDoc;
10 import javax.servlet.http.HttpServletResponse JavaDoc;
11
12 import org.contineo.actions.rest.CheckoutDocumentRestAction;
13 import org.contineo.actions.rest.DeleteFolderOrDocRESTAction;
14 import org.contineo.actions.rest.GetDocumentMetaRESTAction;
15 import org.contineo.actions.rest.GetDocumentRESTAction;
16 import org.contineo.actions.rest.GetFolderContentRESTAction;
17 import org.contineo.actions.rest.PostDocumentRESTAction;
18 import org.contineo.actions.rest.CreateFolderOrDocRESTAction;
19 import org.contineo.admin.dao.UserDAO;
20 import org.contineo.core.CryptBean;
21 import org.contineo.core.config.SettingConfigurator;
22
23 /**
24  * @author Sebastian Stein
25  */

26 public class RestAPI extends HttpServlet JavaDoc {
27     private static final long serialVersionUID = 1L;
28
29     /** provided user name */
30     private String JavaDoc userName;
31     
32     /** URL points to the REST interface */
33     private String JavaDoc localRESTUrl;
34     
35     /** response object; is send to the client */
36     private HttpServletResponse JavaDoc response;
37     
38     /** request object; contains the request received from the client */
39     private HttpServletRequest JavaDoc request;
40     
41     /**
42      * this is contineo's REST web service interface
43      * @author Sebastian Stein
44      */

45     public void service(HttpServletRequest JavaDoc p_request,
46                         HttpServletResponse JavaDoc p_response)
47                         throws IOException JavaDoc, ServletException JavaDoc {
48         // save response and request to local variables
49
response = p_response;
50         request = p_request;
51         
52         // first check if REST interface is enabled
53
SettingConfigurator conf = new SettingConfigurator();
54         String JavaDoc enabledStr = conf.getValue("enablerest");
55         if (! enabledStr.equalsIgnoreCase("true")) {
56             // REST interface is disabled!
57
response.sendError(HttpStatusCodes.FORBIDDEN);
58             return;
59         } else {
60             // first extract the requested service URL
61
String JavaDoc serviceUrl = extractUrls();
62             if (serviceUrl == null || serviceUrl.length() == 0) {
63                 response.sendError(HttpStatusCodes.INTERNAL_SERVER_ERROR);
64                 return;
65             }
66             
67             // split the service URL; if we get nothing the URL is not pointing to a service
68
// so we return an error
69
String JavaDoc[] serviceParameters = splitServiceUrl(serviceUrl);
70             if (serviceParameters == null || serviceParameters.length == 0) {
71                 response.sendError(HttpStatusCodes.BAD_REQUEST);
72                 return;
73             }
74             
75             // check if the provided credentials can be used to login to contineo
76
if (isAuthValid() == false) {
77                 response.sendError(HttpStatusCodes.FORBIDDEN);
78                 return;
79             }
80             
81             // the first part of the URL specifies the requested resource
82
String JavaDoc resource = serviceParameters[0];
83             if (resource.equalsIgnoreCase("document")) {
84                 // we should handle documents
85
processDocument(serviceParameters, request.getMethod());
86                 return;
87             } else if (resource.equalsIgnoreCase("folder")) {
88                 // we should handle a folder
89
processFolder(serviceParameters, request.getMethod());
90                 return;
91             } else {
92                 // we do not support other resources
93
response.sendError(HttpStatusCodes.BAD_REQUEST);
94                 return;
95             }
96         }
97     }
98
99     /**
100      * handles all requests concerning documents
101      * @param serviceParameters the parameters given in the URL
102      * @param httpMethod HTTP method used (GET, POST)
103      * @param response we should send our response to this object
104      */

105     private void processFolder(String JavaDoc[] serviceParameters, String JavaDoc httpMethod) throws IOException JavaDoc {
106         
107         // we need the requested folder; this should be the first and only parameter;
108
// note: serviceParameters[0] contains the requested resource, so the 1st parameter is at [1]
109
int menuId;
110         if (serviceParameters.length == 1) {
111             menuId = 5;
112         } else {
113             try {
114                 menuId = Integer.parseInt(serviceParameters[1]);
115             } catch (NumberFormatException JavaDoc ex) {
116                 response.sendError(HttpStatusCodes.BAD_REQUEST);
117                 return;
118             }
119         }
120
121         // we only support HTTP GET for this resource
122
if (httpMethod.equalsIgnoreCase("get")) {
123             // get folder content
124
GetFolderContentRESTAction getFolderAction =
125                 new GetFolderContentRESTAction(response, userName, localRESTUrl, menuId);
126             if (getFolderAction.isSuccessful() == true)
127                 response.setStatus(getFolderAction.getHttpStatusCode());
128             else
129                 response.sendError(getFolderAction.getHttpStatusCode());
130         } else if (httpMethod.equalsIgnoreCase("put")) {
131             // create a new sub-folder
132
CreateFolderOrDocRESTAction putFolderAction =
133                 new CreateFolderOrDocRESTAction(response, userName, localRESTUrl, menuId, request);
134             if (putFolderAction.isSuccessful() == true)
135                 response.setStatus(putFolderAction.getHttpStatusCode());
136             else
137                 response.sendError(putFolderAction.getHttpStatusCode());
138             
139         } else if (httpMethod.equalsIgnoreCase("delete")) {
140             // delete folder XX
141
DeleteFolderOrDocRESTAction deleteFolderAction =
142                 new DeleteFolderOrDocRESTAction(response, userName, localRESTUrl, menuId, true);
143             if (deleteFolderAction.isSuccessful() == true) {
144                 response.setStatus(deleteFolderAction.getHttpStatusCode());
145             } else {
146                 response.sendError(deleteFolderAction.getHttpStatusCode());
147             }
148         } else {
149             response.sendError(HttpStatusCodes.METHOD_NOT_ALLOWED);
150             return;
151         }
152         
153         return;
154     }
155
156     /**
157      * handles all requests concerning folders
158      * @param serviceParameters the parameters given in the URL
159      * @param httpMethod HTTP method used (GET)
160      */

161     private void processDocument(String JavaDoc[] serviceParameters, String JavaDoc httpMethod) throws IOException JavaDoc {
162         int menuId;
163         String JavaDoc docVersion = null;
164         
165         // there must be at least another parameter specifying the document
166
if (serviceParameters.length == 1) {
167             response.sendError(HttpStatusCodes.BAD_REQUEST);
168             return;
169         } else {
170             try {
171                 // it must be a number
172
menuId = Integer.parseInt(serviceParameters[1]);
173             } catch (NumberFormatException JavaDoc ex) {
174                 response.sendError(HttpStatusCodes.BAD_REQUEST);
175                 return;
176             }
177         }
178         
179         // now check about the HTTP method
180
if (httpMethod.equalsIgnoreCase("get")) {
181             // GET document/XX*/YY --> download document XX (or a certain version YY of XX)
182
// GET document/XX*/meta --> download the meta data of document XX
183
// GET document/XX*/checkout --> checkout document XX
184
if (serviceParameters.length > 3) {
185                 response.sendError(HttpStatusCodes.BAD_REQUEST);
186                 return;
187             }
188
189             // lets check if we have another parameter
190
if (serviceParameters.length == 3) {
191                 String JavaDoc para3 = null;
192                 para3 = serviceParameters[2];
193                 if (para3.equalsIgnoreCase("meta")) {
194                     // get meta data of the document
195
GetDocumentMetaRESTAction getDocMetaAction = new GetDocumentMetaRESTAction("get-meta.xsd",
196                                                                         localRESTUrl, userName, response,
197                                                                         menuId);
198                     if (getDocMetaAction.isSuccessful() == true)
199                         response.setStatus(getDocMetaAction.getHttpStatusCode());
200                     else
201                         response.sendError(getDocMetaAction.getHttpStatusCode());
202                     return;
203                 } else if (para3.equalsIgnoreCase("checkout")) {
204                     // checkout the document and send it to the client
205
CheckoutDocumentRestAction checkoutDocAction = new CheckoutDocumentRestAction(null,
206                                                                             localRESTUrl, userName,
207                                                                             response, menuId);
208                     if (checkoutDocAction.isSuccessful() == true)
209                         response.setStatus(checkoutDocAction.getHttpStatusCode());
210                     else
211                         response.sendError(checkoutDocAction.getHttpStatusCode());
212                     return;
213                 } else {
214                     // if the last parameter is neither meta nor checkout, it must be
215
// the name/id of a certain version of the document
216
docVersion = para3;
217                 }
218             }
219             // GET document/XX (version /YY must not be given)
220
GetDocumentRESTAction getDocumentAction = new GetDocumentRESTAction(null, localRESTUrl, userName,
221                                                                                 response, menuId, docVersion);
222             if (getDocumentAction.isSuccessful() == true)
223                 response.setStatus(getDocumentAction.getHttpStatusCode());
224             else
225                 response.sendError(getDocumentAction.getHttpStatusCode());
226             return;
227             
228         } else if (httpMethod.equalsIgnoreCase("post")) {
229             // POST document/XX* --> checkin document XX
230
if (serviceParameters.length > 2) {
231                 response.sendError(HttpStatusCodes.BAD_REQUEST);
232                 return;
233             }
234             PostDocumentRESTAction postDocAction = new PostDocumentRESTAction("post-version.xsd", localRESTUrl,
235                                                                                userName, response, menuId, request);
236             if (postDocAction.isSuccessful() == true)
237                 response.setStatus(postDocAction.getHttpStatusCode());
238             else
239                 response.sendError(postDocAction.getHttpStatusCode());
240             return;
241         } else if (httpMethod.equalsIgnoreCase("delete")) {
242             // DELETE document/XX* --> deletes the document XX
243
if (serviceParameters.length > 2) {
244                 response.sendError(HttpStatusCodes.BAD_REQUEST);
245                 return;
246             }
247             DeleteFolderOrDocRESTAction deleteDocAction =
248                 new DeleteFolderOrDocRESTAction(response, userName, localRESTUrl, menuId, false);
249             if (deleteDocAction.isSuccessful() == true)
250                 response.setStatus(deleteDocAction.getHttpStatusCode());
251             else
252                 response.sendError(deleteDocAction.getHttpStatusCode());
253         } else {
254             response.sendError(HttpStatusCodes.METHOD_NOT_ALLOWED);
255             return;
256         }
257     }
258
259     /**
260      * checks, if credentials were provided in the HTTP headers and if the client
261      * can be authenticated using those credentials
262      * @return true means client is allowed to access, false means client is not allowed
263      */

264     private boolean isAuthValid() {
265         userName = request.getHeader("X-username");
266         String JavaDoc password = request.getHeader("X-password");
267         
268         // if there are no such headers, we say access forbidden
269
if (userName == null || userName.equals("") ||
270                 password == null || password.equals(""))
271             return false;
272         
273         // do the check
274
password = CryptBean.cryptString(password);
275         
276         UserDAO userDao = new UserDAO();
277         return userDao.validateUser(userName, password);
278
279 // userName = "admin";
280
// return true;
281
}
282     
283     /**
284      * splits the service URL in parts
285      * @return null, if the service URL can't be split in a meaningful way
286      */

287     private String JavaDoc[] splitServiceUrl(String JavaDoc serviceUrl) {
288         String JavaDoc[] parts = serviceUrl.split("/");
289         
290         // if there are no parts, no service is requested -> invalid
291
if (parts.length == 0)
292             return null;
293         
294         // it might be that the first part is empty; if not we
295
// already found all parts and can return them
296
if (!parts[0].equalsIgnoreCase(""))
297             return parts;
298         
299         // the first part is empty, so there must be at least another
300
// part or the URL is invalid
301
if (parts.length <= 1)
302             return null;
303         
304         // now eliminate the first empty part by copying
305
// all parts (without the empty one) to a new string
306
String JavaDoc[] retParts = new String JavaDoc[parts.length - 1];
307         
308         for (int i = 1; i < parts.length; i++)
309             retParts[i - 1] = parts[i];
310         
311         return retParts;
312     }
313
314     /**
315      * extracts the requested service URL, the servlet URL, the REST interface URL
316      */

317     private String JavaDoc extractUrls() {
318         // /contineo (path of contineo on server)
319
String JavaDoc contextPath = request.getContextPath();
320         
321         // /rest (location of this servlet taken from web.xml)
322
String JavaDoc servletPath = request.getServletPath();
323         
324         // /contineo/rest/document/1
325
String JavaDoc requestUri = request.getRequestURI().toString();
326         
327         // build the URL pointing to the REST interface: http://localhost:8080/contineo/rest/
328
localRESTUrl = request.getScheme() + "://" + request.getServerName() + ":" +
329                                 String.valueOf(request.getServerPort()) + contextPath +
330                                 servletPath + "/";
331         
332         // extract the service part by removing the generic part ((context + servlet path) of the URL
333
String JavaDoc toBeRemovedStr = contextPath + servletPath;
334         return requestUri.replaceFirst(toBeRemovedStr, "");
335     }
336 }
Popular Tags