/*
* $Id: RestActionMapper.java 1097499 2011-04-28 15:15:49Z mcucchiara $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.struts2.rest;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
/**
*
* @author yao.he 对Struts2 Rest插件的改写 方便使用其他非rest方式的action
*/
public class RestActionMapper extends DefaultActionMapper {
protected static final Logger LOG = LoggerFactory
.getLogger(RestActionMapper.class);
public static final String HTTP_METHOD_PARAM = "_method";
private String idParameterName = "id";
private String indexMethodName = "index";
private String getMethodName = "show";
private String postMethodName = "create";
private String editMethodName = "edit";
private String newMethodName = "editNew";
private String deleteMethodName = "destroy";
private String putMethodName = "update";
private String optionsMethodName = "options";
private String postContinueMethodName = "createContinue";
private String putContinueMethodName = "updateContinue";
private boolean allowDynamicMethodCalls = true;
public RestActionMapper() {
}
public String getIdParameterName() {
return idParameterName;
}
@Inject(required = false, value = StrutsConstants.STRUTS_ID_PARAMETER_NAME)
public void setIdParameterName(String idParameterName) {
this.idParameterName = idParameterName;
}
@Inject(required = false, value = "struts.mapper.indexMethodName")
public void setIndexMethodName(String indexMethodName) {
this.indexMethodName = indexMethodName;
}
@Inject(required = false, value = "struts.mapper.getMethodName")
public void setGetMethodName(String getMethodName) {
this.getMethodName = getMethodName;
}
@Inject(required = false, value = "struts.mapper.postMethodName")
public void setPostMethodName(String postMethodName) {
this.postMethodName = postMethodName;
}
@Inject(required = false, value = "struts.mapper.editMethodName")
public void setEditMethodName(String editMethodName) {
this.editMethodName = editMethodName;
}
@Inject(required = false, value = "struts.mapper.newMethodName")
public void setNewMethodName(String newMethodName) {
this.newMethodName = newMethodName;
}
@Inject(required = false, value = "struts.mapper.deleteMethodName")
public void setDeleteMethodName(String deleteMethodName) {
this.deleteMethodName = deleteMethodName;
}
@Inject(required = false, value = "struts.mapper.putMethodName")
public void setPutMethodName(String putMethodName) {
this.putMethodName = putMethodName;
}
@Inject(required = false, value = "struts.mapper.optionsMethodName")
public void setOptionsMethodName(String optionsMethodName) {
this.optionsMethodName = optionsMethodName;
}
@Inject(required = false, value = "struts.mapper.postContinueMethodName")
public void setPostContinueMethodName(String postContinueMethodName) {
this.postContinueMethodName = postContinueMethodName;
}
@Inject(required = false, value = "struts.mapper.putContinueMethodName")
public void setPutContinueMethodName(String putContinueMethodName) {
this.putContinueMethodName = putContinueMethodName;
}
@Inject(required = false, value = StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)
public void setAllowDynamicMethodCalls(String allowDynamicMethodCalls) {
this.allowDynamicMethodCalls = "true"
.equalsIgnoreCase(allowDynamicMethodCalls);
}
public ActionMapping getMapping(HttpServletRequest request,
ConfigurationManager configManager) {
ActionMapping mapping = new ActionMapping();
String uri = getUri(request);
uri = dropExtension(uri, mapping);
if (uri == null) {
return null;
}
parseNameAndNamespace(uri, mapping, configManager);
// added by yao.he 2012-5-8
if (!"/rest".equals(mapping.getNamespace()))
return super.getMapping(request, configManager);
handleSpecialParameters(request, mapping);
if (mapping.getName() == null) {
return null;
}
// handle "name!method" convention.
handleDynamicMethodInvocation(mapping, mapping.getName());
String fullName = mapping.getName();
// Only try something if the action name is specified
if (fullName != null && fullName.length() > 0) {
// cut off any ;jsessionid= type appendix but allow the rails-like
// ;edit
int scPos = fullName.indexOf(';');
if (scPos > -1 && !"edit".equals(fullName.substring(scPos + 1))) {
fullName = fullName.substring(0, scPos);
}
int lastSlashPos = fullName.lastIndexOf('/');
String id = null;
if (lastSlashPos > -1) {
// fun trickery to parse 'actionName/id/methodName' in the case
// of 'animals/dog/edit'
int prevSlashPos = fullName.lastIndexOf('/', lastSlashPos - 1);
if (prevSlashPos > -1) {
mapping.setMethod(fullName.substring(lastSlashPos + 1));
fullName = fullName.substring(0, lastSlashPos);
lastSlashPos = prevSlashPos;
}
id = fullName.substring(lastSlashPos + 1);
}
// If a method hasn't been explicitly named, try to guess using
// ReST-style patterns
if (mapping.getMethod() == null) {
if (isOptions(request)) {
mapping.setMethod(optionsMethodName);
// Handle uris with no id, possibly ending in '/'
} else if (lastSlashPos == -1
|| lastSlashPos == fullName.length() - 1) {
// Index e.g. foo
if (isGet(request)) {
mapping.setMethod(indexMethodName);
// Creating a new entry on POST e.g. foo
} else if (isPost(request)) {
if (isExpectContinue(request)) {
mapping.setMethod(postContinueMethodName);
} else {
mapping.setMethod(postMethodName);
}
}
// Handle uris with an id at the end
} else if (id != null) {
// Viewing the form to edit an item e.g. foo/1;edit
if (isGet(request) && id.endsWith(";edit")) {
id = id.substring(0, id.length() - ";edit".length());
mapping.setMethod(editMethodName);
// Viewing the form to create a new item e.g. foo/new
} else if (isGet(request) && "new".equals(id)) {
mapping.setMethod(newMethodName);
// Removing an item e.g. foo/1
} else if (isDelete(request)) {
mapping.setMethod(deleteMethodName);
// Viewing an item e.g. foo/1
} else if (isGet(request)) {
mapping.setMethod(getMethodName);
// Updating an item e.g. foo/1
} else if (isPut(request)) {
if (isExpectContinue(request)) {
mapping.setMethod(putContinueMethodName);
} else {
mapping.setMethod(putMethodName);
}
}