/*
* Copyright 2004-2014 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.rest.mock;
import com.eviware.soapui.config.RESTMockActionConfig;
import com.eviware.soapui.config.RESTMockServiceConfig;
import com.eviware.soapui.impl.rest.RestMethod;
import com.eviware.soapui.impl.rest.RestRequest;
import com.eviware.soapui.impl.rest.RestResource;
import com.eviware.soapui.impl.rest.support.RestUtils;
import com.eviware.soapui.impl.support.AbstractMockService;
import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunContext;
import com.eviware.soapui.impl.wsdl.support.HelpUrls;
import com.eviware.soapui.model.iface.Operation;
import com.eviware.soapui.model.mock.MockDispatcher;
import com.eviware.soapui.model.mock.MockOperation;
import com.eviware.soapui.model.project.Project;
import java.util.ArrayList;
import java.util.List;
import static com.eviware.soapui.impl.rest.RestRequestInterface.HttpMethod;
public class RestMockService extends AbstractMockService<RestMockAction, RESTMockServiceConfig> {
public final static String ICON_NAME = "/restMockService.gif";
public static final String STRING_ID = "REST";
public String getStringID() {
return STRING_ID;
}
public RestMockService(Project project, RESTMockServiceConfig config) {
super(config, project, ICON_NAME);
List<RESTMockActionConfig> restActionConfigList = config.getRestMockActionList();
for (RESTMockActionConfig restActionConfig : restActionConfigList) {
RestMockAction restMockAction = new RestMockAction(this, restActionConfig);
addMockOperation(restMockAction);
}
if (!getConfig().isSetProperties()) {
getConfig().addNewProperties();
}
setPropertiesConfig(config.getProperties());
}
@Override
public String getIconName() {
return ICON_NAME;
}
@Override
public MockDispatcher createDispatcher(WsdlMockRunContext mockContext) {
return new RestMockDispatcher(this, mockContext);
}
public RestMockAction addNewMockAction(RestRequest restRequest) {
RestMockAction mockAction = addEmptyMockAction(restRequest.getMethod(),
RestUtils.getExpandedPath(restRequest.getPath(), restRequest.getParams(), restRequest));
mockAction.setResource(restRequest.getResource());
return mockAction;
}
public RestMockAction addEmptyMockAction(HttpMethod method, String path) {
RESTMockActionConfig config = getConfig().addNewRestMockAction();
String slashifiedPath = slashify(path);
String name = path;
config.setName(name);
config.setMethod(method.name());
config.setResourcePath(slashifiedPath);
RestMockAction restMockAction = new RestMockAction(this, config);
addMockOperation(restMockAction);
fireMockOperationAdded(restMockAction);
return restMockAction;
}
public MockOperation findOrCreateNewOperation(RestRequest restRequest) {
String expandedPath = RestUtils.getExpandedPath(restRequest.getPath(), restRequest.getParams(), restRequest);
MockOperation matchedOperation = findMatchingOperationWithExactPath(expandedPath, restRequest.getMethod());
if (matchedOperation == null) {
matchedOperation = addNewMockAction(restRequest);
}
return matchedOperation;
}
protected MockOperation findBestMatchedOperation(String pathToFind, HttpMethod verbToFind) {
boolean includePartialMatch = true;
return findMatchedOperation(pathToFind, verbToFind, includePartialMatch);
}
protected MockOperation findMatchingOperationWithExactPath(String pathToFind, HttpMethod verbToFind) {
boolean dontIncludePartialMatch = false;
return findMatchedOperation(pathToFind, verbToFind, dontIncludePartialMatch);
}
private MockOperation findMatchedOperation(String pathToFind, HttpMethod verbToFind, boolean includePartialMatch) {
MockOperation bestMatchedOperation = null;
for (MockOperation operation : getMockOperationList()) {
String operationPath = ((RestMockAction) operation).getResourcePath();
HttpMethod operationVerb = ((RestMockAction) operation).getMethod();
boolean matchesPath = operationPath.equals(pathToFind);
boolean matchesVerb = verbToFind == operationVerb;
boolean matchesPathPartially = pathToFind.startsWith(operationPath);
if (matchesPath && matchesVerb) {
return operation;
} else if (includePartialMatch && matchesPathPartially && matchesVerb) {
bestMatchedOperation = getBestMatchedOperation(bestMatchedOperation, operation, operationPath);
}
}
return bestMatchedOperation;
}
private MockOperation getBestMatchedOperation(MockOperation currentBestMatchedOperation, MockOperation operation, String operationPath) {
MockOperation bestMatchedOperation = currentBestMatchedOperation;
if (bestMatchedOperation == null || foundBetterMatch((RestMockAction) bestMatchedOperation, operationPath)) {
bestMatchedOperation = operation;
}
return bestMatchedOperation;
}
private boolean foundBetterMatch(RestMockAction bestMatchedOperation, String operationPath) {
return bestMatchedOperation.getResourcePath().length() < operationPath.length();
}
public boolean canIAddAMockOperation(RestMockAction mockOperation) {
return this.getConfig().getRestMockActionList().contains(mockOperation.getConfig());
}
@Override
public MockOperation addNewMockOperation(Operation operation) {
return addNewMockOperationsFromResource((RestResource) operation).get(0);
}
public List<MockOperation> addNewMockOperationsFromResource(RestResource restResource) {
List<MockOperation> actions = new ArrayList<MockOperation>();
String path = RestUtils.getExpandedPath(restResource.getFullPath(), restResource.getParams(), restResource);
if (restResource.getRestMethodCount() < 1) {
actions.add(addEmptyMockAction(HttpMethod.GET, path));
}
for (RestMethod restMethod : restResource.getRestMethodList()) {
actions.add(addEmptyMockAction(restMethod.getMethod(), path));
}
return actions;
}
private String slashify(String path) {
if (!path.startsWith("/") && !path.isEmpty()) {
return "/" + path;
}
return path;
}
@Override
public String getHelpUrl() {
return HelpUrls.REST_MOCKSERVICE_HELP_URL;
}
}