/modules/restpathactions/java/src/org/jpublish/module/restpathactions/RestPathAction.java
Java | 206 lines | 129 code | 41 blank | 36 comment | 37 complexity | 9c72df2d4f0a143473eeb4bf4fccfb69 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
- /*
- * Copyright (c) 2009. Florin T.PATRASCU
- *
- * 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.jpublish.module.restpathactions;
- import com.anthonyeden.lib.config.Configuration;
- import com.atlassian.util.profiling.UtilTimerStack;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.wink.common.internal.uritemplate.UriTemplateMatcher;
- import org.jpublish.JPublishContext;
- import org.jpublish.RepositoryWrapper;
- import org.jpublish.action.Action;
- import org.jpublish.util.FileCopyUtils;
- import org.jpublish.util.PathUtilities;
- import javax.servlet.http.HttpServletResponse;
- import javax.ws.rs.core.MultivaluedMap;
- import java.io.ByteArrayInputStream;
- import java.io.InputStream;
- import java.util.List;
- import java.util.Map;
- /**
- * @author <a href="mailto:florin.patrascu@gmail.com">Florin T.PATRASCU</a>
- * @since $Revision$ (created: Oct 5, 2010 6:21:35 PM)
- */
- public class RestPathAction implements Action {
- protected static final Log log = LogFactory.getLog(RestPathAction.class);
- public static final String EMPTY_STRING = "";
- public static final String GENERIC_PATH_INFO = "RestPathGenericAction";
- RestPathActionsModule module;
- String modulePath;
- public RestPathAction(String modulePath, RestPathActionsModule module) {
- this.modulePath = modulePath;
- this.module = module;
- }
- public void execute(JPublishContext context, Configuration configuration) throws Exception {
- String method = context.getRequest().getMethod(); // no need .toUpperCase() it
- String pathInfo = GENERIC_PATH_INFO;
- boolean resourceNotFound = true;
- try {
- pathInfo = context.getRequest().getPathInfo();
- String path = pathInfo.replaceFirst(modulePath, EMPTY_STRING);
- if (module.isProfiling()) {
- UtilTimerStack.push(pathInfo);
- }
- for (RestPathActionModel rm : module.getRestModels()) {
- final UriTemplateMatcher matcher = rm.matcher();
- boolean methodMatchesToo = rm.getMethods() != null && rm.getMethods().contains(method);
- if (matcher.matches(path) && methodMatchesToo) {
- resourceNotFound = false;
- if (module.isDebug()) {
- log.info(matcher.toString());
- }
- MultivaluedMap<String, String> multivaluedMap = matcher.getVariables(true);
- for (Map.Entry<String, List<String>> entry : multivaluedMap.entrySet()) {
- if (entry.getValue() != null) {
- context.put(entry.getKey(),
- entry.getValue().size() > 1
- ? entry.getValue()
- : entry.getValue().get(0));
- }
- }
- module.execute(rm.getAction(), context, rm.getConfiguration());
- String content = null;
- final String pagePath = rm.getPage();
- String viewType = rm.getContentType();
- if (pagePath != null) {
- RepositoryWrapper repository = (RepositoryWrapper) context.get(module.getDefaultRepository());
- viewType = PathUtilities.extractPageType(pagePath);
- if (repository != null) {
- content = repository.get(pagePath);
- }
- }
- if (content == null) {
- content = (String) context.get(RestPathActionsModule.RESPONSE);
- }
- HttpServletResponse response = context.getResponse();
- if (content != null && response != null) {
- InputStream in;
- if (content == null) {
- content = EMPTY_STRING;
- }
- String callback = context.getRequest().getParameter(module.getCallbackParameter());
- if (method.equalsIgnoreCase("get") && callback != null) { //experimental code
- content = String.format("%s( %s)", callback, content);
- }
- in = new ByteArrayInputStream(content.getBytes(
- module.getSite()
- .getCharacterEncodingManager()
- .getMap(path).getResponseEncoding()));
- setResponseContentType(context, path, viewType);
- long contentLength = FileCopyUtils.copy(in, response.getOutputStream());
- response.setContentLength((int) contentLength);
- }
- break;
- }
- }
- if (resourceNotFound) {
- if (module.isDebug()) {
- log.info(String.format("%s not found;", pathInfo));
- }
- context.getResponse().setStatus(HttpServletResponse.SC_NOT_FOUND);
- }
- } finally {
- context.setStopProcessing();
- if (module.isProfiling()) {
- UtilTimerStack.pop(pathInfo);
- }
- }
- }
- /**
- * guessing the content type as follows:
- * - if a format request parameter is defined and it is not null, else we look for the page type and
- * we'll try finding a declared MIME type
- *
- * @param context the JPublish current page context
- * @param viewType the file extension of the view used to fallback for setting the content type
- * @param path the page path from the request
- */
- private void setResponseContentType(JPublishContext context, String path, String viewType) {
- String format = null;
- String userFormat = null;
- String pageType = PathUtilities.extractPageType(path);
- if (module.getFormatParameter() != null) {
- userFormat = context.getRequest().getParameter(module.getFormatParameter());
- format = userFormat != null ? userFormat : pageType;
- }
- String mimeType = (String) module.getSite().getMimeTypeMap().get(format);
- if (mimeType == null) {
- if (viewType != null) {
- mimeType = (String) module.getSite().getMimeTypeMap().get(viewType.trim().toLowerCase());
- }
- if (mimeType == null) { // fall back on the default mimeType
- mimeType = module.getSite().getMimeTypeMap().getDefaultMimeType();
- }
- }
- String contentType = getMimeTypeWithCharset(mimeType,
- module.getSite().getCharacterEncodingManager().getMap(path).getResponseEncoding());
- context.getResponse().setContentType(contentType);
- //todo: injecting a format.[json|xml|and_so_on] into the context???
- }
- /**
- * Append the charset to the given mime type.
- *
- * @param mimeType The mime type
- * @param charSet The character set
- * @return The full mimetype + character set
- */
- private String getMimeTypeWithCharset(String mimeType, String charSet) {
- StringBuilder buffer = new StringBuilder();
- buffer.append(mimeType).append("; charset=").append(charSet);
- return buffer.toString();
- }
- }