org.joda.beans.gen.BeanGenConfig Maven / Gradle / Ivy
/*
* Copyright 2001-present Stephen Colebourne
*
* 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.joda.beans.gen;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* Configuration for the code generator.
*/
public final class BeanGenConfig {
/**
* The copy generators.
*/
private static final Charset UTF8 = Charset.availableCharsets().get("UTF-8");
/**
* The copy generators.
*/
private final Map copyGenerators;
/**
* The builder types.
*/
private final Map builderTypes;
/**
* The builder generators.
*/
private final Map builderGenerators;
/**
* The invalid immutable types.
*/
private final Set invalidImmutableTypes;
/**
* The immutable varargs code.
*/
private final Map immutableVarArgs;
/**
* The immutable get clones.
*/
private final Map immutableGetClones;
/**
* The indent to use.
*/
private String indent = " ";
/**
* The field prefix to use.
*/
private String prefix = "";
/**
* The end of line separator
*/
private String eol = System.lineSeparator();
/**
* The default style to use.
*/
private String defaultStyle = "smart";
/**
* Whether to add the generated annotation.
*/
private boolean generatedAnno;
/**
* Parses the configuration file.
*
* This loads the file as an ini file in this package.
*
* @param resourceLocator the configuration resource locator, not null
* @return the configuration
*/
public static BeanGenConfig parse(String resourceLocator) {
String fullFile;
if (resourceLocator.contains("/") || resourceLocator.endsWith(".ini")) {
fullFile = resourceLocator;
} else if (resourceLocator.equals("jdk6")) { // compatibility
fullFile = "org/joda/beans/gen/jdk.ini";
} else {
fullFile = "org/joda/beans/gen/" + resourceLocator + ".ini";
}
ClassLoader loader = BeanGenConfig.class.getClassLoader();
if (loader == null) {
throw new IllegalArgumentException("ClassLoader was null: " + fullFile);
}
URL url = loader.getResource(fullFile);
if (url == null) {
throw new IllegalArgumentException("Configuration file not found: " + fullFile);
}
List lines = new ArrayList<>();
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(url.openStream(), UTF8));
String line = in.readLine();
while (line != null) {
if (line.trim().startsWith("#") == false && line.trim().length() > 0) {
lines.add(line);
}
line = in.readLine();
}
return parse(lines);
} catch (IOException ex) {
throw new RuntimeException(ex.getMessage(), ex);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex1) {
// ignore
}
}
}
}
private static BeanGenConfig parse(List lines) {
Map immutableCopiers = new HashMap<>();
Map mutableCopiers = new HashMap<>();
Map immutableGetClones = new HashMap<>();
Map immutableVarArgs = new HashMap<>();
Map builderInits = new HashMap<>();
Map builderTypes = new HashMap<>();
Set invalidImmutableTypes = new HashSet<>();
for (ListIterator iterator = lines.listIterator(); iterator.hasNext(); ) {
String line = iterator.next().trim();
if (line.equals("[immutable.builder.to.immutable]")) {
while (iterator.hasNext()) {
line = iterator.next().trim();
if (line.startsWith("[")) {
iterator.previous();
break;
}
int pos = line.indexOf('=');
if (pos <= 0) {
throw new IllegalArgumentException("Invalid ini file line: " + line);
}
String key = line.substring(0, pos).trim();
String value = line.substring(pos + 1).trim();
immutableCopiers.put(key, value);
}
} else if (line.equals("[immutable.builder.to.mutable]")) {
while (iterator.hasNext()) {
line = iterator.next().trim();
if (line.startsWith("[")) {
iterator.previous();
break;
}
int pos = line.indexOf('=');
if (pos <= 0) {
throw new IllegalArgumentException("Invalid ini file line: " + line);
}
String key = line.substring(0, pos).trim();
String value = line.substring(pos + 1).trim();
mutableCopiers.put(key, value);
}
} else if (line.equals("[immutable.invalid.type]")) {
while (iterator.hasNext()) {
line = iterator.next().trim();
int pos = line.indexOf('=');
if (pos <= 0) {
throw new IllegalArgumentException("Invalid ini file line: " + line);
}
String key = line.substring(0, pos).trim();
invalidImmutableTypes.add(key);
}
} else if (line.equals("[immutable.get.clone]")) {
while (iterator.hasNext()) {
line = iterator.next().trim();
if (line.startsWith("[")) {
iterator.previous();
break;
}
int pos = line.indexOf('=');
if (pos <= 0) {
throw new IllegalArgumentException("Invalid ini file line: " + line);
}
String key = line.substring(0, pos).trim();
String value = line.substring(pos + 1).trim();
if (value.equals("clone") == false && value.equals("cloneCast") == false) {
throw new IllegalArgumentException("Value for [immutable.get.clone] must be 'clone' or 'cloneCast'");
}
immutableGetClones.put(key, value);
}
} else if (line.equals("[immutable.builder.varargs]")) {
while (iterator.hasNext()) {
line = iterator.next().trim();
if (line.startsWith("[")) {
iterator.previous();
break;
}
int pos = line.indexOf('=');
if (pos <= 0) {
throw new IllegalArgumentException("Invalid ini file line: " + line);
}
String key = line.substring(0, pos).trim();
String value = line.substring(pos + 1).trim();
immutableVarArgs.put(key, value);
}
} else if (line.equals("[immutable.builder.type]")) {
while (iterator.hasNext()) {
line = iterator.next().trim();
if (line.startsWith("[")) {
iterator.previous();
break;
}
int pos = line.indexOf('=');
if (pos <= 0) {
throw new IllegalArgumentException("Invalid ini file line: " + line);
}
String key = line.substring(0, pos).trim();
String value = line.substring(pos + 1).trim();
builderTypes.put(key, value);
}
} else if (line.equals("[immutable.builder.init]")) {
while (iterator.hasNext()) {
line = iterator.next().trim();
if (line.startsWith("[")) {
iterator.previous();
break;
}
int pos = line.indexOf('=');
if (pos <= 0) {
throw new IllegalArgumentException("Invalid ini file line: " + line);
}
String key = line.substring(0, pos).trim();
String value = line.substring(pos + 1).trim();
builderInits.put(key, value);
}
} else {
throw new IllegalArgumentException("Invalid ini file section: " + line);
}
}
// adjust to results
Map builderGenerators = new HashMap<>();
for (Entry entry : builderInits.entrySet()) {
String type = builderTypes.get(entry.getKey());
if (type == null) {
type = entry.getKey() + "<>";
}
builderGenerators.put(entry.getKey(), new BuilderGen.PatternBuilderGen(type, entry.getValue()));
}
Map copyGenerators = new HashMap<>();
for (Entry entry : immutableCopiers.entrySet()) {
String fieldType = entry.getKey();
String immutableCopier = entry.getValue();
String mutableCopier = mutableCopiers.get(fieldType);
if (mutableCopier == null) {
throw new IllegalArgumentException("[immutable.builder.to.immutable] and [immutable.builder.to.mutable] entries must match: " + fieldType);
}
copyGenerators.put(fieldType, new CopyGen.PatternCopyGen(immutableCopier, mutableCopier));
}
return new BeanGenConfig(copyGenerators, builderGenerators, builderTypes, invalidImmutableTypes, immutableVarArgs, immutableGetClones);
}
//-----------------------------------------------------------------------
/**
* Creates an instance.
*
* @param copyGenerators the copy generators, not null
* @param builderGenerators the builder generators, not null
* @param builderTypes the builder types, not null
* @param invalidImmutableTypes the invalid immutable types, not null
* @param immutableVarArgs the varargs code
* @param immutableGetClones the get clone code
*/
private BeanGenConfig(
Map copyGenerators,
Map builderGenerators,
Map builderTypes,
Set invalidImmutableTypes,
Map immutableVarArgs,
Map immutableGetClones) {
this.copyGenerators = copyGenerators;
this.builderGenerators = builderGenerators;
this.builderTypes = builderTypes;
this.invalidImmutableTypes = invalidImmutableTypes;
this.immutableVarArgs = immutableVarArgs;
this.immutableGetClones = immutableGetClones;
}
//-----------------------------------------------------------------------
/**
* The copy generators.
*
* @return the generators, not null
*/
public Map getCopyGenerators() {
return copyGenerators;
}
/**
* The builder generators.
*
* @return the generators, not null
*/
public Map getBuilderGenerators() {
return builderGenerators;
}
/**
* The builder types.
*
* @return the types, not null
*/
public Map getBuilderTypes() {
return builderTypes;
}
/**
* The invalid immutable types.
*
* @return the invalid immutable types, not null
*/
public Set getInvalidImmutableTypes() {
return invalidImmutableTypes;
}
/**
* The builder varargs code.
*
* @return the varargs, not null
*/
public Map getImmutableVarArgs() {
return immutableVarArgs;
}
/**
* The builder types.
*
* @return the types, not null
*/
public Map getImmutableGetClones() {
return immutableGetClones;
}
//-----------------------------------------------------------------------
/**
* Gets the indent to use.
*
* @return the indent, not null
*/
public String getIndent() {
return indent;
}
/**
* Sets the indent to use.
*
* @param indent the indent to use, not null
*/
public void setIndent(String indent) {
this.indent = indent;
}
/**
* Gets the prefix to use.
*
* @return the prefix, not null
*/
public String getPrefix() {
return prefix;
}
/**
* Sets the prefix to use.
*
* @param prefix the prefix to use, not null
*/
public void setPrefix(String prefix) {
this.prefix = prefix;
}
/**
* Gets the end of line separator to use.
*
* @return the end of line, not null
*/
public String getEol() {
return eol;
}
/**
* Sets the end of line separator to use.
*
* @param eol the end of line separator to use, not null
*/
public void setEol(String eol) {
this.eol = eol;
}
/**
* Gets the default style to use.
*
* @return the default style, not null
*/
public String getDefaultStyle() {
return defaultStyle;
}
/**
* Sets the default style to use.
*
* @param defaultStyle the default style to use, not null
*/
public void setDefaultStyle(String defaultStyle) {
this.defaultStyle = defaultStyle;
}
/**
* Gets whether to add the generated annotation.
*
* @return whether to add the generated annotation, not null
*/
public boolean isGeneratedAnno() {
return generatedAnno;
}
/**
* Sets whether to add the generated annotation.
*
* @param generatedAnno whether to add the generated annotation
*/
public void setGeneratedAnno(boolean generatedAnno) {
this.generatedAnno = generatedAnno;
}
}