Refactored more to java

This commit is contained in:
Marcin Grzejszczak
2019-09-24 12:32:25 +02:00
parent 9b52f11023
commit af3f0a06c6
9 changed files with 422 additions and 303 deletions

View File

@@ -1,175 +0,0 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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.springframework.cloud.contract.verifier.converter
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import groovy.transform.CompileStatic
import groovy.util.logging.Commons
import wiremock.com.google.common.collect.ListMultimap
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import org.springframework.cloud.contract.verifier.file.ContractFileScanner
import org.springframework.cloud.contract.verifier.file.ContractFileScannerBuilder
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.cloud.contract.verifier.util.NamesUtil
import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter
/**
* Recursively converts contracts into their stub representations
*
* @since 1.1.0
*/
@Commons
@CompileStatic
class RecursiveFilesConverter {
private final StubGeneratorProvider holder
private final File outMappingsDir
private final File contractsDslDir
private final List<String> excludedFiles
private final String includedContracts
private final boolean excludeBuildFolders
// Use constructor without ContractVerifierConfigProperties
@Deprecated
RecursiveFilesConverter(ContractVerifierConfigProperties props, StubGeneratorProvider holder = null) {
this(props.stubsOutputDir, props.contractsDslDir, props.excludedFiles, props.includedContracts, props.excludeBuildFolders, holder)
}
// Use constructor without ContractVerifierConfigProperties
@Deprecated
RecursiveFilesConverter(ContractVerifierConfigProperties props, File stubsOutputDir, StubGeneratorProvider holder = null) {
this(stubsOutputDir, props.contractsDslDir, props.excludedFiles, props.includedContracts, props.excludeBuildFolders, holder)
}
RecursiveFilesConverter(File stubsOutputDir, File contractsDslDir, List<String> excludedFiles,
String includedContracts, boolean excludeBuildFolders, StubGeneratorProvider holder = null) {
this.outMappingsDir = stubsOutputDir
this.contractsDslDir = contractsDslDir
this.excludedFiles = excludedFiles
this.includedContracts = includedContracts
this.excludeBuildFolders = excludeBuildFolders
this.holder = holder ?: new StubGeneratorProvider()
}
void processFiles() {
ContractFileScanner scanner = new ContractFileScannerBuilder()
.baseDir(contractsDslDir)
.excluded(excludedFiles as Set)
.ignored([] as Set)
.included([] as Set)
.includeMatcher(includedContracts)
.build()
ListMultimap<Path, ContractMetadata> contracts = scanner.findContracts()
if (log.isDebugEnabled()) {
log.debug("Found the following contracts $contracts")
}
contracts.asMap().entrySet().each { entry ->
entry.value.each { ContractMetadata contract ->
if (log.isDebugEnabled()) {
log.debug("Will create a stub for contract [${contract}]")
}
File sourceFile = contract.path.toFile()
Collection<StubGenerator> stubGenerators = contract.convertedContract ? holder.
allOrDefault(new DslToWireMockClientConverter()) :
holder.converterForName(sourceFile.name)
try {
String path = sourceFile.path
if (excludeBuildFolders
&& (
matchesPath(path, "target") || matchesPath(path, "build"))) {
if (log.isDebugEnabled()) {
log.debug("Exclude build folder is set. Path [${path}] contains [target] or [build] in its path")
}
return
}
if (!contract.convertedContract && !stubGenerators) {
return
}
int contractsSize = contract.convertedContract.size()
def entryKey = entry.key
if (log.isDebugEnabled()) {
log.debug("Stub Generators [${stubGenerators}] will convert contents of [${entryKey}]")
}
stubGenerators.each { StubGenerator stubGenerator ->
Map<Contract, String> convertedContent = stubGenerator.
convertContents(entryKey.last().toString(), contract)
if (!convertedContent) {
return
}
convertedContent.entrySet().
eachWithIndex { Map.Entry<Contract, String> content, int index ->
Contract dsl = content.key
String converted = content.value
if (converted) {
Path absoluteTargetPath =
createAndReturnTargetDirectory(sourceFile)
File newJsonFile =
createTargetFileWithProperName(stubGenerator, absoluteTargetPath,
sourceFile, contractsSize, index, dsl)
newJsonFile.setText(converted, StandardCharsets.UTF_8.
toString())
}
}
}
}
catch (Exception e) {
throw new ConversionContractVerifierException("Unable to make conversion of ${sourceFile.name}", e)
}
}
}
}
private boolean matchesPath(String path, String folder) {
return path.matches("^.*${File.separator}${folder}${File.separator}.*\$")
}
private Path createAndReturnTargetDirectory(File sourceFile) {
Path relativePath = Paths.get(contractsDslDir.toURI()).
relativize(sourceFile.parentFile.toPath())
Path absoluteTargetPath = outMappingsDir.toPath().resolve(relativePath)
Files.createDirectories(absoluteTargetPath)
return absoluteTargetPath
}
private File createTargetFileWithProperName(StubGenerator stubGenerator, Path absoluteTargetPath,
File sourceFile, int contractsSize, int index, Contract dsl) {
String name = generateName(dsl, contractsSize, stubGenerator, sourceFile, index)
File newJsonFile = new File(absoluteTargetPath.toFile(), name)
log.info("Creating new stub [$newJsonFile.path]")
return newJsonFile
}
private String generateName(Contract dsl, int contractsSize, StubGenerator converter,
File sourceFile, int index) {
String generatedName = converter.generateOutputFileNameForInput(sourceFile.name)
boolean hasDot = NamesUtil.hasDot(generatedName)
String extension = hasDot ? NamesUtil.afterLastDot(generatedName) : ""
if (dsl.name && extension) {
return "${dsl.name}.${extension}"
}
else if (contractsSize == 1) {
return generatedName
}
return "${index}_${generatedName}"
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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.springframework.cloud.contract.verifier.converter
import groovy.transform.CompileStatic
import org.springframework.core.io.support.SpringFactoriesLoader
/**
* Retrieves file converters from the class path and operates on them.
*
* @author Marcin Grzejszczak
* @since 1.1.0
*/
@CompileStatic
class StubGeneratorProvider {
private final List<StubGenerator> converters = []
StubGeneratorProvider() {
this.converters.addAll(SpringFactoriesLoader.loadFactories(StubGenerator, null))
}
StubGeneratorProvider(List<StubGenerator> converters) {
this.converters.addAll(converters)
}
Collection<StubGenerator> converterForName(String fileName) {
return this.converters.findAll { it.canHandleFileName(fileName) }
}
Collection<StubGenerator> allOrDefault(StubGenerator defaultStubGenerator) {
return this.converters.empty ? [defaultStubGenerator] : this.converters
}
}

View File

@@ -1,58 +0,0 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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.springframework.cloud.contract.verifier.wiremock
import groovy.transform.CompileStatic
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.cloud.contract.verifier.util.NamesUtil
/**
* Converts DSLs to WireMock stubs
*
* @since 1.0.0
*/
@CompileStatic
class DslToWireMockClientConverter extends DslToWireMockConverter {
private String convertASingleContract(String rootName, ContractMetadata contract, Contract dsl) {
return new WireMockStubStrategy(rootName, contract, dsl).toWireMockClientStub()
}
@Override
Map<Contract, String> convertContents(String rootName, ContractMetadata contract) {
if (!(contract.convertedContract.any { it.request })) {
return [:]
}
if (contract.convertedContract.size() == 1) {
return [(contract.convertedContract.first()):
convertASingleContract(rootName, contract, contract.convertedContract.
first())]
}
Map<Contract, String> convertedContracts = [:]
contract.convertedContract.findAll { it.request }.
eachWithIndex { Contract dsl, int index ->
String name = dsl.name ? NamesUtil.
convertIllegalPackageChars(dsl.name) : "${rootName}_${index}"
convertedContracts << [(dsl): convertASingleContract(name, contract, dsl)]
}
return convertedContracts
}
}

View File

@@ -14,21 +14,19 @@
* limitations under the License.
*/
package org.springframework.cloud.contract.verifier.converter
package org.springframework.cloud.contract.verifier.converter;
import groovy.transform.CompileStatic
import org.springframework.cloud.contract.spec.ContractVerifierException
import org.springframework.cloud.contract.spec.ContractVerifierException;
/**
* Thrown when a a DSL can't be properly converted
* Thrown when a a DSL can't be properly converted.
*
* @since 1.0.0
*/
@CompileStatic
class ConversionContractVerifierException extends ContractVerifierException {
public class ConversionContractVerifierException extends ContractVerifierException {
ConversionContractVerifierException(String message, Throwable cause) {
super(message, cause)
public ConversionContractVerifierException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,261 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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.springframework.cloud.contract.verifier.converter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import wiremock.com.google.common.collect.ListMultimap;
import org.springframework.cloud.contract.spec.Contract;
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties;
import org.springframework.cloud.contract.verifier.file.ContractFileScanner;
import org.springframework.cloud.contract.verifier.file.ContractFileScannerBuilder;
import org.springframework.cloud.contract.verifier.file.ContractMetadata;
import org.springframework.cloud.contract.verifier.util.NamesUtil;
import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter;
import org.springframework.util.StringUtils;
/**
* Recursively converts contracts into their stub representations.
*
* @since 1.1.0
*/
public class RecursiveFilesConverter {
private static final Log log = LogFactory.getLog(RecursiveFilesConverter.class);
private final StubGeneratorProvider holder;
private final File outMappingsDir;
private final File contractsDslDir;
private final List<String> excludedFiles;
private final String includedContracts;
private final boolean excludeBuildFolders;
@Deprecated
public RecursiveFilesConverter(ContractVerifierConfigProperties props,
StubGeneratorProvider holder) {
this(props.getStubsOutputDir(), props.getContractsDslDir(),
props.getExcludedFiles(), props.getIncludedContracts(),
props.getExcludeBuildFolders(), holder);
}
@Deprecated
public RecursiveFilesConverter(ContractVerifierConfigProperties props) {
this(props.getStubsOutputDir(), props.getContractsDslDir(),
props.getExcludedFiles(), props.getIncludedContracts(),
props.getExcludeBuildFolders(), null);
}
@Deprecated
public RecursiveFilesConverter(ContractVerifierConfigProperties props,
File stubsOutputDir) {
this(stubsOutputDir, props.getContractsDslDir(), props.getExcludedFiles(),
props.getIncludedContracts(), props.getExcludeBuildFolders(), null);
}
@Deprecated
public RecursiveFilesConverter(ContractVerifierConfigProperties props,
File stubsOutputDir, StubGeneratorProvider holder) {
this(stubsOutputDir, props.getContractsDslDir(), props.getExcludedFiles(),
props.getIncludedContracts(), props.getExcludeBuildFolders(), holder);
}
public RecursiveFilesConverter(File stubsOutputDir, File contractsDslDir,
List<String> excludedFiles, String includedContracts,
boolean excludeBuildFolders, StubGeneratorProvider holder) {
this.outMappingsDir = stubsOutputDir;
this.contractsDslDir = contractsDslDir;
this.excludedFiles = excludedFiles;
this.includedContracts = includedContracts;
this.excludeBuildFolders = excludeBuildFolders;
this.holder = holder == null ? new StubGeneratorProvider() : holder;
}
public RecursiveFilesConverter(File stubsOutputDir, File contractsDslDir,
List<String> excludedFiles, String includedContracts,
boolean excludeBuildFolders) {
this(stubsOutputDir, contractsDslDir, excludedFiles, includedContracts,
excludeBuildFolders, null);
}
public void processFiles() {
ContractFileScanner scanner = new ContractFileScannerBuilder()
.baseDir(contractsDslDir).excluded(new HashSet<>(excludedFiles))
.ignored(new HashSet<>()).included(new HashSet<>())
.includeMatcher(includedContracts).build();
ListMultimap<Path, ContractMetadata> contracts = scanner.findContracts();
if (log.isDebugEnabled()) {
log.debug("Found the following contracts " + contracts);
}
for (Map.Entry<Path, Collection<ContractMetadata>> entry : contracts.asMap()
.entrySet()) {
for (ContractMetadata contract : entry.getValue()) {
if (log.isDebugEnabled()) {
log.debug("Will create a stub for contract [" + contract + "]");
}
File sourceFile = contract.getPath().toFile();
Collection<StubGenerator> stubGenerators = contract
.getConvertedContract() != null
? holder.allOrDefault(new DslToWireMockClientConverter())
: holder.converterForName(sourceFile.getName());
try {
String path = sourceFile.getPath();
if (excludeBuildFolders && (matchesPath(path, "target")
|| matchesPath(path, "build"))) {
if (log.isDebugEnabled()) {
log.debug("Exclude build folder is set. Path [" + path
+ "] contains [target] or [build] in its path");
}
continue;
}
if (nullOrEmpty(contract) && nullOrEmpty(stubGenerators)) {
continue;
}
int contractsSize = contract.getConvertedContract().size();
Path entryKey = entry.getKey();
if (log.isDebugEnabled()) {
log.debug("Stub Generators [" + stubGenerators
+ "] will convert contents of [" + entryKey + "]");
}
for (StubGenerator stubGenerator : stubGenerators) {
Map<Contract, String> convertedContent = stubGenerator
.convertContents(last(entryKey).toString(), contract);
if (convertedContent == null || convertedContent.isEmpty()) {
continue;
}
Set<Map.Entry<Contract, String>> entrySet = convertedContent
.entrySet();
Iterator<Map.Entry<Contract, String>> iterator = entrySet
.iterator();
int index = 0;
while (iterator.hasNext()) {
Map.Entry<Contract, String> content = iterator.next();
Contract dsl = content.getKey();
String converted = content.getValue();
if (StringUtils.hasText(converted)) {
Path absoluteTargetPath = createAndReturnTargetDirectory(
sourceFile);
File newJsonFile = createTargetFileWithProperName(
stubGenerator, absoluteTargetPath, sourceFile,
contractsSize, index, dsl);
Files.write(newJsonFile.toPath(),
Collections.singletonList(converted),
StandardCharsets.UTF_8);
}
index = index + 1;
}
}
}
catch (Exception e) {
throw new ConversionContractVerifierException(
"Unable to make conversion of " + sourceFile.getName(), e);
}
}
}
}
private static <T> T last(Iterable<T> self) {
Iterator<T> iterator = self.iterator();
if (!iterator.hasNext()) {
throw new NoSuchElementException(
"Cannot access last() element from an empty Iterable");
}
T result = null;
while (iterator.hasNext()) {
result = iterator.next();
}
return result;
}
private boolean nullOrEmpty(ContractMetadata contract) {
return contract.getConvertedContract() == null
|| nullOrEmpty(contract.getConvertedContract());
}
private boolean nullOrEmpty(Collection collection) {
return collection == null || collection.isEmpty();
}
private boolean matchesPath(String path, String folder) {
return path.matches("^.*" + File.separator + folder + File.separator + ".*$");
}
private Path createAndReturnTargetDirectory(File sourceFile) {
Path relativePath = Paths.get(contractsDslDir.toURI())
.relativize(sourceFile.getParentFile().toPath());
Path absoluteTargetPath = outMappingsDir.toPath().resolve(relativePath);
try {
Files.createDirectories(absoluteTargetPath);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
return absoluteTargetPath;
}
private File createTargetFileWithProperName(StubGenerator stubGenerator,
Path absoluteTargetPath, File sourceFile, int contractsSize, int index,
Contract dsl) {
String name = generateName(dsl, contractsSize, stubGenerator, sourceFile, index);
File newJsonFile = new File(absoluteTargetPath.toFile(), name);
log.info("Creating new stub [" + newJsonFile.getPath() + "]");
return newJsonFile;
}
private String generateName(Contract dsl, int contractsSize, StubGenerator converter,
File sourceFile, int index) {
String generatedName = converter
.generateOutputFileNameForInput(sourceFile.getName());
boolean hasDot = NamesUtil.hasDot(generatedName);
String extension = hasDot ? NamesUtil.afterLastDot(generatedName) : "";
if (StringUtils.hasText(dsl.getName()) && StringUtils.hasText(extension)) {
return dsl.getName() + "." + extension;
}
else if (contractsSize == 1) {
return generatedName;
}
return index + "_" + generatedName;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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.springframework.cloud.contract.verifier.converter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.core.io.support.SpringFactoriesLoader;
/**
* Retrieves file converters from the class path and operates on them.
*
* @author Marcin Grzejszczak
* @since 1.1.0
*/
public class StubGeneratorProvider {
public StubGeneratorProvider() {
this.converters
.addAll(SpringFactoriesLoader.loadFactories(StubGenerator.class, null));
}
public StubGeneratorProvider(List<StubGenerator> converters) {
this.converters.addAll(converters);
}
public Collection<StubGenerator> converterForName(final String fileName) {
return this.converters.stream()
.filter(stubGenerator -> stubGenerator.canHandleFileName(fileName))
.collect(Collectors.toList());
}
public Collection<StubGenerator> allOrDefault(StubGenerator defaultStubGenerator) {
return this.converters.isEmpty() ? Collections.singletonList(defaultStubGenerator)
: this.converters;
}
private final List<StubGenerator> converters = new ArrayList<StubGenerator>();
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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.springframework.cloud.contract.verifier.wiremock;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import org.springframework.cloud.contract.spec.Contract;
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy;
import org.springframework.cloud.contract.verifier.file.ContractMetadata;
import org.springframework.cloud.contract.verifier.util.NamesUtil;
import org.springframework.util.StringUtils;
/**
* Converts DSLs to WireMock stubs.
*
* @since 1.0.0
*/
public class DslToWireMockClientConverter extends DslToWireMockConverter {
private String convertASingleContract(String rootName, ContractMetadata contract,
Contract dsl) {
return new WireMockStubStrategy(rootName, contract, dsl).toWireMockClientStub();
}
@Override
public Map<Contract, String> convertContents(String rootName,
ContractMetadata contract) {
List<Contract> httpContracts = httpContracts(contract);
if (httpContracts.isEmpty()) {
return new HashMap<>();
}
if (contract.getConvertedContract().size() == 1) {
return Collections.singletonMap(
first((List<Contract>) contract.getConvertedContract()),
convertASingleContract(rootName, contract,
first((List<Contract>) contract.getConvertedContract())));
}
return convertContracts(rootName, contract, httpContracts);
}
private List<Contract> httpContracts(ContractMetadata contract) {
return contract.getConvertedContract().stream()
.filter(c -> c.getRequest() != null).collect(Collectors.toList());
}
private Map<Contract, String> convertContracts(String rootName,
ContractMetadata contract, List<Contract> contractsWithRequest) {
Map<Contract, String> convertedContracts = new LinkedHashMap<>();
for (int i = 0; i < contractsWithRequest.size(); i++) {
Contract dsl = contractsWithRequest.get(i);
String name = StringUtils.hasText(dsl.getName())
? NamesUtil.convertIllegalPackageChars(dsl.getName())
: rootName + "_" + i;
convertedContracts.put(dsl, convertASingleContract(name, contract, dsl));
}
return convertedContracts;
}
private static <T> T first(List<T> self) {
if (self.isEmpty()) {
throw new NoSuchElementException(
"Cannot access first() element from an empty List");
}
return self.get(0);
}
}

View File

@@ -14,30 +14,28 @@
* limitations under the License.
*/
package org.springframework.cloud.contract.verifier.wiremock
package org.springframework.cloud.contract.verifier.wiremock;
import groovy.transform.CompileStatic
import org.springframework.cloud.contract.verifier.converter.StubGenerator
import org.springframework.cloud.contract.verifier.converter.StubGenerator;
/**
* WireMock implementation of the {@link StubGenerator}
* WireMock implementation of the {@link StubGenerator}.
*
* @since 1.0.0
*/
@CompileStatic
abstract class DslToWireMockConverter implements StubGenerator {
public abstract class DslToWireMockConverter implements StubGenerator {
@Override
String generateOutputFileNameForInput(String inputFileName) {
return inputFileName.replaceAll(extension(inputFileName), 'json')
public String generateOutputFileNameForInput(String inputFileName) {
return inputFileName.replaceAll(extension(inputFileName), "json");
}
private String extension(String inputFileName) {
int i = inputFileName.lastIndexOf('.')
int i = inputFileName.lastIndexOf(".");
if (i > 0) {
return inputFileName.substring(i + 1)
return inputFileName.substring(i + 1);
}
return ""
return "";
}
}