PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/restpathactions/java/src/org/jpublish/module/restpathactions/RestPathAction.java

http://jpublish.googlecode.com/
Java | 206 lines | 129 code | 41 blank | 36 comment | 37 complexity | 9c72df2d4f0a143473eeb4bf4fccfb69 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
  1. /*
  2. * Copyright (c) 2009. Florin T.PATRASCU
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.jpublish.module.restpathactions;
  17. import com.anthonyeden.lib.config.Configuration;
  18. import com.atlassian.util.profiling.UtilTimerStack;
  19. import org.apache.commons.logging.Log;
  20. import org.apache.commons.logging.LogFactory;
  21. import org.apache.wink.common.internal.uritemplate.UriTemplateMatcher;
  22. import org.jpublish.JPublishContext;
  23. import org.jpublish.RepositoryWrapper;
  24. import org.jpublish.action.Action;
  25. import org.jpublish.util.FileCopyUtils;
  26. import org.jpublish.util.PathUtilities;
  27. import javax.servlet.http.HttpServletResponse;
  28. import javax.ws.rs.core.MultivaluedMap;
  29. import java.io.ByteArrayInputStream;
  30. import java.io.InputStream;
  31. import java.util.List;
  32. import java.util.Map;
  33. /**
  34. * @author <a href="mailto:florin.patrascu@gmail.com">Florin T.PATRASCU</a>
  35. * @since $Revision$ (created: Oct 5, 2010 6:21:35 PM)
  36. */
  37. public class RestPathAction implements Action {
  38. protected static final Log log = LogFactory.getLog(RestPathAction.class);
  39. public static final String EMPTY_STRING = "";
  40. public static final String GENERIC_PATH_INFO = "RestPathGenericAction";
  41. RestPathActionsModule module;
  42. String modulePath;
  43. public RestPathAction(String modulePath, RestPathActionsModule module) {
  44. this.modulePath = modulePath;
  45. this.module = module;
  46. }
  47. public void execute(JPublishContext context, Configuration configuration) throws Exception {
  48. String method = context.getRequest().getMethod(); // no need .toUpperCase() it
  49. String pathInfo = GENERIC_PATH_INFO;
  50. boolean resourceNotFound = true;
  51. try {
  52. pathInfo = context.getRequest().getPathInfo();
  53. String path = pathInfo.replaceFirst(modulePath, EMPTY_STRING);
  54. if (module.isProfiling()) {
  55. UtilTimerStack.push(pathInfo);
  56. }
  57. for (RestPathActionModel rm : module.getRestModels()) {
  58. final UriTemplateMatcher matcher = rm.matcher();
  59. boolean methodMatchesToo = rm.getMethods() != null && rm.getMethods().contains(method);
  60. if (matcher.matches(path) && methodMatchesToo) {
  61. resourceNotFound = false;
  62. if (module.isDebug()) {
  63. log.info(matcher.toString());
  64. }
  65. MultivaluedMap<String, String> multivaluedMap = matcher.getVariables(true);
  66. for (Map.Entry<String, List<String>> entry : multivaluedMap.entrySet()) {
  67. if (entry.getValue() != null) {
  68. context.put(entry.getKey(),
  69. entry.getValue().size() > 1
  70. ? entry.getValue()
  71. : entry.getValue().get(0));
  72. }
  73. }
  74. module.execute(rm.getAction(), context, rm.getConfiguration());
  75. String content = null;
  76. final String pagePath = rm.getPage();
  77. String viewType = rm.getContentType();
  78. if (pagePath != null) {
  79. RepositoryWrapper repository = (RepositoryWrapper) context.get(module.getDefaultRepository());
  80. viewType = PathUtilities.extractPageType(pagePath);
  81. if (repository != null) {
  82. content = repository.get(pagePath);
  83. }
  84. }
  85. if (content == null) {
  86. content = (String) context.get(RestPathActionsModule.RESPONSE);
  87. }
  88. HttpServletResponse response = context.getResponse();
  89. if (content != null && response != null) {
  90. InputStream in;
  91. if (content == null) {
  92. content = EMPTY_STRING;
  93. }
  94. String callback = context.getRequest().getParameter(module.getCallbackParameter());
  95. if (method.equalsIgnoreCase("get") && callback != null) { //experimental code
  96. content = String.format("%s( %s)", callback, content);
  97. }
  98. in = new ByteArrayInputStream(content.getBytes(
  99. module.getSite()
  100. .getCharacterEncodingManager()
  101. .getMap(path).getResponseEncoding()));
  102. setResponseContentType(context, path, viewType);
  103. long contentLength = FileCopyUtils.copy(in, response.getOutputStream());
  104. response.setContentLength((int) contentLength);
  105. }
  106. break;
  107. }
  108. }
  109. if (resourceNotFound) {
  110. if (module.isDebug()) {
  111. log.info(String.format("%s not found;", pathInfo));
  112. }
  113. context.getResponse().setStatus(HttpServletResponse.SC_NOT_FOUND);
  114. }
  115. } finally {
  116. context.setStopProcessing();
  117. if (module.isProfiling()) {
  118. UtilTimerStack.pop(pathInfo);
  119. }
  120. }
  121. }
  122. /**
  123. * guessing the content type as follows:
  124. * - if a format request parameter is defined and it is not null, else we look for the page type and
  125. * we'll try finding a declared MIME type
  126. *
  127. * @param context the JPublish current page context
  128. * @param viewType the file extension of the view used to fallback for setting the content type
  129. * @param path the page path from the request
  130. */
  131. private void setResponseContentType(JPublishContext context, String path, String viewType) {
  132. String format = null;
  133. String userFormat = null;
  134. String pageType = PathUtilities.extractPageType(path);
  135. if (module.getFormatParameter() != null) {
  136. userFormat = context.getRequest().getParameter(module.getFormatParameter());
  137. format = userFormat != null ? userFormat : pageType;
  138. }
  139. String mimeType = (String) module.getSite().getMimeTypeMap().get(format);
  140. if (mimeType == null) {
  141. if (viewType != null) {
  142. mimeType = (String) module.getSite().getMimeTypeMap().get(viewType.trim().toLowerCase());
  143. }
  144. if (mimeType == null) { // fall back on the default mimeType
  145. mimeType = module.getSite().getMimeTypeMap().getDefaultMimeType();
  146. }
  147. }
  148. String contentType = getMimeTypeWithCharset(mimeType,
  149. module.getSite().getCharacterEncodingManager().getMap(path).getResponseEncoding());
  150. context.getResponse().setContentType(contentType);
  151. //todo: injecting a format.[json|xml|and_so_on] into the context???
  152. }
  153. /**
  154. * Append the charset to the given mime type.
  155. *
  156. * @param mimeType The mime type
  157. * @param charSet The character set
  158. * @return The full mimetype + character set
  159. */
  160. private String getMimeTypeWithCharset(String mimeType, String charSet) {
  161. StringBuilder buffer = new StringBuilder();
  162. buffer.append(mimeType).append("; charset=").append(charSet);
  163. return buffer.toString();
  164. }
  165. }