Convert from groovy to java (#1478)
This commit is contained in:
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.file.Files
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Commons
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.ContractConverter
|
||||
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader
|
||||
|
||||
/**
|
||||
* Converts contracts to YAML for the given folder
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@CompileStatic
|
||||
@Commons
|
||||
class ToYamlConverter {
|
||||
|
||||
private ToYamlConverter() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class")
|
||||
}
|
||||
|
||||
private static YamlContractConverter yamlContractConverter = new YamlContractConverter()
|
||||
|
||||
private static final List<ContractConverter> CONTRACT_CONVERTERS = converters()
|
||||
|
||||
protected static void doReplaceContractWithYaml(ContractConverter converter, File file) {
|
||||
// base dir: target/copied_contracts/contracts/
|
||||
// target/copied_contracts/contracts/foo/baz/bar.groovy
|
||||
Collection<Contract> collection = converter.convertFrom(file)
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Converted file [" + file + "] to collection of ["
|
||||
+ collection.
|
||||
size()
|
||||
+ "] contracts")
|
||||
}
|
||||
List<YamlContract> yamls = yamlContractConverter.convertTo(collection)
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Converted collection of ["
|
||||
+ collection.
|
||||
size()
|
||||
+ "] contracts to ["
|
||||
+ yamls.size()
|
||||
+ "] YAML contracts")
|
||||
}
|
||||
// rm target/copied_contracts/contracts/foo/baz/bar.groovy
|
||||
file.delete()
|
||||
// [contracts/foo/baz/bar.groovy] -> [contracts/foo/baz/bar.yml]
|
||||
Map<String, byte[]> stored = yamlContractConverter.store(yamls)
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Dumped YAMLs to following file names " + stored.keySet())
|
||||
}
|
||||
stored.entrySet().each {
|
||||
File ymlContractVersion = new File(file.parentFile, it.getKey())
|
||||
// store the YMLs instead of groovy files
|
||||
Files.write(ymlContractVersion.toPath(), it.getValue())
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Written file [" + ymlContractVersion + "] with YAML contract definition")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a contract ends with e.g. [.groovy] we will move it to the [original]
|
||||
* folder, convert the [.groovy] version to [.yml] and store it instead
|
||||
* of the Groovy file. From that we will continue processing as if
|
||||
* from the very beginning there was only a [.yml] file
|
||||
*
|
||||
* @param baseDir
|
||||
*/
|
||||
static void replaceContractWithYaml(File baseDir) {
|
||||
baseDir.eachFileRecurse { File file ->
|
||||
ContractConverter converter = CONTRACT_CONVERTERS.find {
|
||||
it.isAccepted(file)
|
||||
}
|
||||
if (converter) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Will replace contract [${file.name}] with a YAML version")
|
||||
}
|
||||
doReplaceContractWithYaml(converter, file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ContractConverter> converters() {
|
||||
List<ContractConverter> converters =
|
||||
SpringFactoriesLoader.loadFactories(ContractConverter, null)
|
||||
converters.add(YamlContractConverter.INSTANCE)
|
||||
converters.add(ContractVerifierDslConverter.INSTANCE)
|
||||
return converters
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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 com.fasterxml.jackson.dataformat.yaml.YAMLMapper
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.ContractConverter
|
||||
/**
|
||||
* Simple converter from and to a {@link YamlContract} to a collection of {@link Contract}
|
||||
*
|
||||
* @since 1.2.1
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Tim Ysewyn
|
||||
*/
|
||||
@Slf4j
|
||||
@CompileStatic
|
||||
class YamlContractConverter implements ContractConverter<List<YamlContract>> {
|
||||
|
||||
public static final YamlContractConverter INSTANCE = new YamlContractConverter()
|
||||
private final YAMLMapper mapper = new YAMLMapper()
|
||||
private final YamlToContracts yamlToContracts = new YamlToContracts()
|
||||
private final ContractsToYaml contractsToYaml = new ContractsToYaml()
|
||||
|
||||
@Override
|
||||
boolean isAccepted(File file) {
|
||||
String name = file.getName()
|
||||
boolean acceptFile = name.endsWith(".yml") || name.endsWith(".yaml")
|
||||
if (acceptFile){
|
||||
try {
|
||||
this.yamlToContracts.convertFrom(file)
|
||||
} catch (e) {
|
||||
log.warn("Error Processing yaml file. Skipping Contract Generation ", e)
|
||||
acceptFile = false
|
||||
}
|
||||
}
|
||||
return acceptFile
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<Contract> convertFrom(File file) {
|
||||
return this.yamlToContracts.convertFrom(file)
|
||||
}
|
||||
|
||||
@Override
|
||||
List<YamlContract> convertTo(Collection<Contract> contracts) {
|
||||
return this.contractsToYaml.convertTo(contracts)
|
||||
}
|
||||
|
||||
@Override
|
||||
Map<String, byte[]> store(List<YamlContract> contracts) {
|
||||
return contracts.collectEntries {
|
||||
return [(name(it)):
|
||||
this.mapper.writeValueAsString(it).bytes]
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
List<YamlContract> read(byte[] bytes) {
|
||||
try {
|
||||
return Collections.singletonList(this.mapper.readValue(bytes, YamlContract))
|
||||
} catch (Exception e) {
|
||||
return this.mapper.readerForListOf(YamlContract.class).readValue(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
protected String name(YamlContract contract) {
|
||||
return (contract.name ?:
|
||||
String.valueOf(Math.abs(contract.hashCode()))) + ".yml"
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.util
|
||||
|
||||
import java.nio.file.FileVisitResult
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.SimpleFileVisitor
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
|
||||
/**
|
||||
* A utility class that helps to convert names
|
||||
*
|
||||
* @author Jakub Kubrynski, codearte.io
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class NamesUtil {
|
||||
|
||||
/**
|
||||
* Returns the first element before the last separator presence.
|
||||
* @return empty string if separator is not found.
|
||||
*/
|
||||
static String beforeLast(String string, String separator) {
|
||||
if (string?.indexOf(separator) > -1) {
|
||||
return string.substring(0, string.lastIndexOf(separator))
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element after the last separator presence
|
||||
* @return the provided string if separator is not found.
|
||||
*/
|
||||
static String afterLast(String string, String separator) {
|
||||
if (hasSeparator(string, separator)) {
|
||||
return string.substring(string.lastIndexOf(separator) + 1)
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if has a separatot in the string
|
||||
*/
|
||||
static boolean hasSeparator(String string, String separator) {
|
||||
return string?.indexOf(separator) > -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element after the last dot presence
|
||||
* @return the provided string if separator is not found.
|
||||
*/
|
||||
static String afterLastDot(String string) {
|
||||
return afterLast(string, '.')
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if has a dot
|
||||
*/
|
||||
static boolean hasDot(String string) {
|
||||
return hasSeparator(string, '.')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file - file with contracts
|
||||
* @param contracts - collection of contracts
|
||||
* @param counter - given contract index
|
||||
* @return the default contract name, resolved from file name, taking
|
||||
* * into consideration also the index of contract (for multiple contracts
|
||||
* * stored in a single file).
|
||||
*/
|
||||
static String defaultContractName(File file, Collection contracts, int counter) {
|
||||
String tillExtension = file.name.substring(0, file.name.lastIndexOf("."))
|
||||
return tillExtension + (counter > 0 || contracts.size() > 1 ? "_" + counter : "")
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string into a camel case format
|
||||
*/
|
||||
static String camelCase(String className) {
|
||||
if (!className) {
|
||||
return className
|
||||
}
|
||||
String firstChar = className.charAt(0).toLowerCase() as String
|
||||
return firstChar + className.substring(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalizes the provided string
|
||||
*/
|
||||
static String capitalize(String className) {
|
||||
if (!className) {
|
||||
return className
|
||||
}
|
||||
String firstChar = className.charAt(0).toUpperCase() as String
|
||||
return firstChar + className.substring(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the whole string to the last present dot.
|
||||
* @return input string if there is no dot
|
||||
*/
|
||||
static String toLastDot(String string) {
|
||||
if (string?.indexOf('.') > -1) {
|
||||
return string.substring(0, string.lastIndexOf('.'))
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the Java package notation to a path format
|
||||
*/
|
||||
static String packageToDirectory(String packageName) {
|
||||
return packageName.replace('.' as char, File.separatorChar)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the path format to a Java package notation
|
||||
*/
|
||||
static String directoryToPackage(String directory) {
|
||||
return directory
|
||||
.replace('.', '_')
|
||||
.replace(File.separator, '.')
|
||||
.replaceAll('\\.([0-9])', '._$1')
|
||||
.replaceAll('^([0-9].*)', '_$1')
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the directories and converts renames illegal folder names
|
||||
* to package names
|
||||
*
|
||||
* @param rootDir - folder from which to start traversing
|
||||
*/
|
||||
static void recrusiveDirectoryToPackage(File rootDir) {
|
||||
try {
|
||||
if (!rootDir.exists()) {
|
||||
return
|
||||
}
|
||||
InvalidFolderRenamer renamer = new InvalidFolderRenamer()
|
||||
Files.walkFileTree(rootDir.toPath(), renamer)
|
||||
renamer.rename()
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex)
|
||||
}
|
||||
}
|
||||
|
||||
private static class InvalidFolderRenamer extends SimpleFileVisitor<Path> {
|
||||
|
||||
private Deque<FileAndNewName> filesToRename = new ArrayDeque<>()
|
||||
|
||||
@Override
|
||||
FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||
String name = dir.toFile().getName()
|
||||
String convertedName = directoryToPackage(name)
|
||||
if (name != convertedName) {
|
||||
this.filesToRename.
|
||||
addFirst(new FileAndNewName(dir.toFile(), convertedName))
|
||||
}
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
|
||||
void rename() {
|
||||
this.filesToRename.each {
|
||||
it.file.renameTo(new File(it.file.parentFile, it.newName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FileAndNewName {
|
||||
private final File file
|
||||
private final String newName
|
||||
|
||||
private FileAndNewName(File file, String newName) {
|
||||
this.file = file
|
||||
this.newName = newName
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts illegal package characters to underscores
|
||||
*/
|
||||
static String convertIllegalPackageChars(String packageName) {
|
||||
return packageName.replaceAll('[_\\- .+]', '_')
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts illegal characters in method names to underscores
|
||||
*/
|
||||
static String convertIllegalMethodNameChars(String methodName) {
|
||||
String result = methodName.replaceAll('^[^a-zA-Z_$0-9]', '_')
|
||||
return result.replaceAll('[^a-zA-Z_$0-9]', '_')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.ContractConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
/**
|
||||
* Converts contracts to YAML for the given folder.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public final class ToYamlConverter {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ToYamlConverter.class);
|
||||
|
||||
private ToYamlConverter() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
private static final YamlContractConverter yamlContractConverter = new YamlContractConverter();
|
||||
|
||||
private static final List<ContractConverter> CONTRACT_CONVERTERS = converters();
|
||||
|
||||
protected static void doReplaceContractWithYaml(ContractConverter converter,
|
||||
File file) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Will replace contract [{}] with a YAML version", file.getName());
|
||||
}
|
||||
// base dir: target/copied_contracts/contracts/
|
||||
// target/copied_contracts/contracts/foo/baz/bar.groovy
|
||||
Collection<Contract> collection = converter.convertFrom(file);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Converted file [{}] to collection of [{}] contracts", file,
|
||||
collection.size());
|
||||
}
|
||||
List<YamlContract> yamls = yamlContractConverter.convertTo(collection);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Converted collection of [{}] contracts to [{}] YAML contracts",
|
||||
collection.size(), yamls.size());
|
||||
}
|
||||
// rm target/copied_contracts/contracts/foo/baz/bar.groovy
|
||||
file.delete();
|
||||
// [contracts/foo/baz/bar.groovy] -> [contracts/foo/baz/bar.yml]
|
||||
Map<String, byte[]> stored = yamlContractConverter.store(yamls);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Dumped YAMLs to following file names {}", stored.keySet());
|
||||
}
|
||||
stored.forEach((key, value) -> {
|
||||
File ymlContractVersion = new File(file.getParentFile(), key);
|
||||
// store the YMLs instead of groovy files
|
||||
try {
|
||||
Files.write(ymlContractVersion.toPath(), value);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Written file [{}] with YAML contract definition",
|
||||
ymlContractVersion);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If a contract ends with e.g. [.groovy] we will move it to the [original] folder,
|
||||
* convert the [.groovy] version to [.yml] and store it instead of the Groovy file.
|
||||
* From that we will continue processing as if from the very beginning there was only
|
||||
* a [.yml] file
|
||||
* @param baseDir base directory for contracts
|
||||
*/
|
||||
public static void replaceContractWithYaml(File baseDir) {
|
||||
try {
|
||||
Files.walk(baseDir.toPath()).map(Path::toFile)
|
||||
.forEach(file -> CONTRACT_CONVERTERS.stream()
|
||||
.filter(converter -> converter.isAccepted(file)).findFirst()
|
||||
.ifPresent(converter -> doReplaceContractWithYaml(converter,
|
||||
file)));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ContractConverter> converters() {
|
||||
List<ContractConverter> converters = SpringFactoriesLoader
|
||||
.loadFactories(ContractConverter.class, null);
|
||||
converters.add(YamlContractConverter.INSTANCE);
|
||||
converters.add(ContractVerifierDslConverter.INSTANCE);
|
||||
return converters;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -429,6 +429,13 @@ public class YamlContract {
|
||||
|
||||
public PredefinedRegex predefined;
|
||||
|
||||
public ValueMatcher() {
|
||||
}
|
||||
|
||||
public ValueMatcher(String regex) {
|
||||
this.regex = regex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.ContractConverter;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
/**
|
||||
* Simple converter from and to a {@link YamlContract} to a collection of
|
||||
* {@link Contract}.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Tim Ysewyn
|
||||
* @since 1.2.1
|
||||
*/
|
||||
public class YamlContractConverter implements ContractConverter<List<YamlContract>> {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(YamlContractConverter.class);
|
||||
|
||||
public static final YamlContractConverter INSTANCE = new YamlContractConverter();
|
||||
|
||||
private final YAMLMapper mapper = new YAMLMapper();
|
||||
|
||||
private final YamlToContracts yamlToContracts = new YamlToContracts();
|
||||
|
||||
private final ContractsToYaml contractsToYaml = new ContractsToYaml();
|
||||
|
||||
@Override
|
||||
public boolean isAccepted(File file) {
|
||||
String name = file.getName();
|
||||
boolean acceptFile = name.endsWith(".yml") || name.endsWith(".yaml");
|
||||
if (acceptFile) {
|
||||
try {
|
||||
this.yamlToContracts.convertFrom(file);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Error Processing yaml file. Skipping Contract Generation ", e);
|
||||
acceptFile = false;
|
||||
}
|
||||
}
|
||||
return acceptFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Contract> convertFrom(File file) {
|
||||
return this.yamlToContracts.convertFrom(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<YamlContract> convertTo(Collection<Contract> contracts) {
|
||||
return this.contractsToYaml.convertTo(contracts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, byte[]> store(List<YamlContract> contracts) {
|
||||
return contracts.stream().collect(toMap(this::name, this::getBytes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<YamlContract> read(byte[] bytes) {
|
||||
try {
|
||||
return singletonList(this.mapper.readValue(bytes, YamlContract.class));
|
||||
}
|
||||
catch (Exception e) {
|
||||
try {
|
||||
return this.mapper.readerForListOf(YamlContract.class).readValue(bytes);
|
||||
}
|
||||
catch (IOException ioException) {
|
||||
throw new RuntimeException(ioException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String name(YamlContract contract) {
|
||||
return StringUtils.defaultIfEmpty(contract.name,
|
||||
String.valueOf(Math.abs((contract.hashCode())))) + ".yml";
|
||||
}
|
||||
|
||||
protected byte[] getBytes(YamlContract yamlContract) {
|
||||
try {
|
||||
return this.mapper.writeValueAsString(yamlContract).getBytes();
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* A utility class that helps to convert names.
|
||||
*
|
||||
* @author Jakub Kubrynski, codearte.io
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class NamesUtil {
|
||||
|
||||
private NamesUtil() {
|
||||
throw new IllegalStateException("Can't instantiate a utility class");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element before the last separator presence.
|
||||
* @return empty string if separator is not found.
|
||||
*/
|
||||
public static String beforeLast(String string, String separator) {
|
||||
if (string != null && string.indexOf(separator) > -1) {
|
||||
return string.substring(0, string.lastIndexOf(separator));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element after the last separator presence.
|
||||
* @return the provided string if separator is not found.
|
||||
*/
|
||||
public static String afterLast(String string, String separator) {
|
||||
if (hasSeparator(string, separator)) {
|
||||
return string.substring(string.lastIndexOf(separator) + 1);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if has a separatot in the string.
|
||||
*/
|
||||
public static boolean hasSeparator(String string, String separator) {
|
||||
return string.indexOf(separator) > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element after the last dot presence.
|
||||
* @return the provided string if separator is not found.
|
||||
*/
|
||||
public static String afterLastDot(String string) {
|
||||
return afterLast(string, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if has a dot
|
||||
*/
|
||||
public static boolean hasDot(String string) {
|
||||
return hasSeparator(string, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file - file with contracts
|
||||
* @param contracts - collection of contracts
|
||||
* @param counter - given contract index
|
||||
* @return the default contract name, resolved from file name, taking * into
|
||||
* consideration also the index of contract (for multiple contracts * stored in a
|
||||
* single file).
|
||||
*/
|
||||
public static String defaultContractName(File file, Collection contracts,
|
||||
int counter) {
|
||||
int lastIndexOfDot = file.getName().lastIndexOf(".");
|
||||
String tillExtension = file.getName().substring(0, lastIndexOfDot);
|
||||
return tillExtension + (counter > 0 || contracts.size() > 1 ? "_" + counter : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string into a camel case format.
|
||||
*/
|
||||
public static String camelCase(String className) {
|
||||
if (isEmpty(className)) {
|
||||
return className;
|
||||
}
|
||||
String firstChar = className.substring(0, 1).toLowerCase();
|
||||
return firstChar + className.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalizes the provided string.
|
||||
*/
|
||||
public static String capitalize(String className) {
|
||||
if (isEmpty(className)) {
|
||||
return className;
|
||||
}
|
||||
String firstChar = className.substring(0, 1).toUpperCase();
|
||||
return firstChar + className.substring(1);
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String string) {
|
||||
return string == null || string.length() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the whole string to the last present dot.
|
||||
* @return input string if there is no dot
|
||||
*/
|
||||
public static String toLastDot(String string) {
|
||||
if (string.indexOf(".") > -1) {
|
||||
return string.substring(0, string.lastIndexOf("."));
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the Java package notation to a path format.
|
||||
*/
|
||||
public static String packageToDirectory(String packageName) {
|
||||
return packageName.replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the path format to a Java package notation.
|
||||
*/
|
||||
public static String directoryToPackage(String directory) {
|
||||
return directory.replace('.', '_').replace(File.separatorChar, '.')
|
||||
.replaceAll("\\.([0-9])", "._$1").replaceAll("^([0-9].*)", "_$1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the directories and converts renames illegal folder names to package
|
||||
* names.
|
||||
* @param rootDir - folder from which to start traversing
|
||||
*/
|
||||
public static void recrusiveDirectoryToPackage(File rootDir) {
|
||||
try {
|
||||
if (!rootDir.exists()) {
|
||||
return;
|
||||
}
|
||||
InvalidFolderRenamer renamer = new InvalidFolderRenamer();
|
||||
Files.walkFileTree(rootDir.toPath(), renamer);
|
||||
renamer.rename();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts illegal package characters to underscores.
|
||||
*/
|
||||
public static String convertIllegalPackageChars(String packageName) {
|
||||
return packageName.replaceAll("[_\\- .+]", "_");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts illegal characters in method names to underscores.
|
||||
*/
|
||||
public static String convertIllegalMethodNameChars(String methodName) {
|
||||
String result = methodName.replaceAll("^[^a-zA-Z_$0-9]", "_");
|
||||
return result.replaceAll("[^a-zA-Z_$0-9]", "_");
|
||||
}
|
||||
|
||||
private static class InvalidFolderRenamer extends SimpleFileVisitor<Path> {
|
||||
|
||||
private final Deque<FileAndNewName> filesToRename = new ArrayDeque<FileAndNewName>();
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||
String name = dir.toFile().getName();
|
||||
String convertedName = directoryToPackage(name);
|
||||
if (!name.equals(convertedName)) {
|
||||
this.filesToRename
|
||||
.addFirst(new FileAndNewName(dir.toFile(), convertedName));
|
||||
}
|
||||
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
public void rename() {
|
||||
this.filesToRename.forEach(fileAndNewName -> {
|
||||
fileAndNewName.file.renameTo(new File(fileAndNewName.file.getParentFile(),
|
||||
fileAndNewName.newName));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class FileAndNewName {
|
||||
|
||||
private FileAndNewName(File file, String newName) {
|
||||
this.file = file;
|
||||
this.newName = newName;
|
||||
}
|
||||
|
||||
private final File file;
|
||||
|
||||
private final String newName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user