- 샘플 생성 로직 리팩토링 - 길이 및 소수 자릿수 기준 상세화 - 공통 스키마 처리 함수 추가 - 코드 중복 제거 및 가독성 향상
This commit is contained in:
@@ -224,6 +224,8 @@
|
|||||||
const s = { type: row.type.value };
|
const s = { type: row.type.value };
|
||||||
if (row.format && row.format.value) s.format = row.format.value;
|
if (row.format && row.format.value) s.format = row.format.value;
|
||||||
if (row.maxLength && row.maxLength.value) s.maxLength = Number(row.maxLength.value);
|
if (row.maxLength && row.maxLength.value) s.maxLength = Number(row.maxLength.value);
|
||||||
|
// 소수 자릿수(GW 레이아웃 유래) 보존 — 예제값 생성 시 '.' 포함 길이 계산에 사용
|
||||||
|
if (row.decimals && row.decimals.value !== '' && row.decimals.value != null) s['x-djb-decimal'] = Number(row.decimals.value);
|
||||||
if (row.pattern && row.pattern.value) s.pattern = row.pattern.value;
|
if (row.pattern && row.pattern.value) s.pattern = row.pattern.value;
|
||||||
if (row.description && row.description.value) s.description = row.description.value;
|
if (row.description && row.description.value) s.description = row.description.value;
|
||||||
if (row.example && row.example.value !== '') s.example = coerceExample(row.type.value, row.example.value);
|
if (row.example && row.example.value !== '') s.example = coerceExample(row.type.value, row.example.value);
|
||||||
@@ -1466,6 +1468,7 @@
|
|||||||
required: { value: false, locked: false },
|
required: { value: false, locked: false },
|
||||||
format: { value: '', locked: false },
|
format: { value: '', locked: false },
|
||||||
maxLength: { value: '', locked: false },
|
maxLength: { value: '', locked: false },
|
||||||
|
decimals: { value: '', locked: false },
|
||||||
pattern: { value: '', locked: false },
|
pattern: { value: '', locked: false },
|
||||||
description: { value: '', locked: false },
|
description: { value: '', locked: false },
|
||||||
example: { value: '', locked: false },
|
example: { value: '', locked: false },
|
||||||
@@ -1480,6 +1483,7 @@
|
|||||||
required: { value: false, locked: false },
|
required: { value: false, locked: false },
|
||||||
format: { value: '', locked: false },
|
format: { value: '', locked: false },
|
||||||
maxLength: { value: '', locked: false },
|
maxLength: { value: '', locked: false },
|
||||||
|
decimals: { value: '', locked: false },
|
||||||
pattern: { value: '', locked: false },
|
pattern: { value: '', locked: false },
|
||||||
description: { value: '', locked: false },
|
description: { value: '', locked: false },
|
||||||
example: { value: '', locked: false }
|
example: { value: '', locked: false }
|
||||||
@@ -1733,6 +1737,7 @@
|
|||||||
var row = {
|
var row = {
|
||||||
name: wrap(name, gw), type: wrap(t, gw), required: wrap(!!required, false),
|
name: wrap(name, gw), type: wrap(t, gw), required: wrap(!!required, false),
|
||||||
format: wrap(p.format || ''), maxLength: wrap(p.maxLength == null ? '' : p.maxLength),
|
format: wrap(p.format || ''), maxLength: wrap(p.maxLength == null ? '' : p.maxLength),
|
||||||
|
decimals: wrap(p['x-djb-decimal'] == null ? '' : p['x-djb-decimal']),
|
||||||
pattern: wrap(p.pattern || ''), description: wrap(p.description || ''),
|
pattern: wrap(p.pattern || ''), description: wrap(p.description || ''),
|
||||||
example: wrap(p.example == null ? '' : p.example), children: null
|
example: wrap(p.example == null ? '' : p.example), children: null
|
||||||
};
|
};
|
||||||
@@ -1782,7 +1787,7 @@
|
|||||||
};
|
};
|
||||||
d.parameters = (op.parameters || []).map(function (p) {
|
d.parameters = (op.parameters || []).map(function (p) {
|
||||||
var s = p.schema || {};
|
var s = p.schema || {};
|
||||||
return { in: p.in || 'query', name: wrap(p.name), type: wrap(s.type || 'string'), required: wrap(!!p.required), format: wrap(s.format || ''), maxLength: wrap(s.maxLength == null ? '' : s.maxLength), pattern: wrap(s.pattern || ''), description: wrap(p.description || ''), example: wrap(p.example == null ? '' : p.example) };
|
return { in: p.in || 'query', name: wrap(p.name), type: wrap(s.type || 'string'), required: wrap(!!p.required), format: wrap(s.format || ''), maxLength: wrap(s.maxLength == null ? '' : s.maxLength), decimals: wrap(s['x-djb-decimal'] == null ? '' : s['x-djb-decimal']), pattern: wrap(s.pattern || ''), description: wrap(p.description || ''), example: wrap(p.example == null ? '' : p.example) };
|
||||||
});
|
});
|
||||||
var rb = op.requestBody || {}; var rbc = rb.content || {}; var mt = Object.keys(rbc)[0] || 'application/json';
|
var rb = op.requestBody || {}; var rbc = rb.content || {}; var mt = Object.keys(rbc)[0] || 'application/json';
|
||||||
d.requestBody = { mediaType: mt, required: wrap(!!rb.required), schema: schemaToRows((rbc[mt] || {}).schema) };
|
d.requestBody = { mediaType: mt, required: wrap(!!rb.required), schema: schemaToRows((rbc[mt] || {}).schema) };
|
||||||
@@ -1827,19 +1832,34 @@
|
|||||||
|
|
||||||
// 스키마 기반 샘플 JSON 생성 (자동생성 예제)
|
// 스키마 기반 샘플 JSON 생성 (자동생성 예제)
|
||||||
function _coerce(t, v) { if (t === 'integer') return parseInt(v, 10) || 0; if (t === 'number') return parseFloat(v) || 0; if (t === 'boolean') return v === true || v === 'true'; return v; }
|
function _coerce(t, v) { if (t === 'integer') return parseInt(v, 10) || 0; if (t === 'number') return parseFloat(v) || 0; if (t === 'boolean') return v === true || v === 'true'; return v; }
|
||||||
// 기본 예제값: string→sample_명(길이 지정 시 맞춰 자름), integer→123456, number→123456.123, boolean→false
|
// 자릿수 문자열: start 위치부터 1~9 를 순환('123456789123...')
|
||||||
// - 숫자는 길이 지정 시 정수부를 그 길이에 맞춰 자름(실수는 소수 .123 유지)
|
function _digits(start, count) { var s = ''; for (var i = 0; i < count; i++) s += String(((start + i) % 9) + 1); return s; }
|
||||||
function _defScalar(t, name, maxLen) {
|
// 숫자 예제값. 길이는 소수점(.)까지 포함한 문자열 전체 길이로 계산한다.
|
||||||
var ml = parseInt(maxLen, 10);
|
// 예) 길이 9 / 소수 5 → 123.45678 (정수부 3 + '.' 1 + 소수부 5 = 9자)
|
||||||
if (t === 'integer') {
|
// - 길이가 소수부+2 보다 짧으면 정수부 1자리를 확보하고 소수부를 줄인다.
|
||||||
var iv = '123456';
|
// - 길이 미지정이면 정수부 6자리(기존 기본값)를 사용한다.
|
||||||
if (ml && ml > 0 && iv.length > ml) iv = iv.substring(0, ml);
|
function _numSample(maxLen, dec) {
|
||||||
return parseInt(iv, 10);
|
var ml = parseInt(maxLen, 10) || 0, d = parseInt(dec, 10) || 0;
|
||||||
|
if (d <= 0) return _digits(0, ml > 0 ? Math.min(ml, 6) : 6);
|
||||||
|
var il;
|
||||||
|
if (ml > 0) {
|
||||||
|
il = ml - d - 1;
|
||||||
|
if (il < 1) { il = 1; d = Math.max(1, ml - 2); }
|
||||||
|
} else {
|
||||||
|
il = 6;
|
||||||
}
|
}
|
||||||
|
return _digits(0, il) + '.' + _digits(il, d);
|
||||||
|
}
|
||||||
|
// 기본 예제값: string→sample_명(길이 지정 시 맞춰 자름), integer→123456, number→123.45678, boolean→false
|
||||||
|
// - 숫자는 지정 길이를 넘지 않도록 자릿수를 맞춘다(소수는 '.' 포함 길이 기준).
|
||||||
|
// - number 인데 소수 자릿수 정보가 없으면 3자리로 가정(소수 0자리는 백엔드가 integer 로 매핑).
|
||||||
|
function _defScalar(t, name, maxLen, decimals) {
|
||||||
|
var ml = parseInt(maxLen, 10);
|
||||||
|
if (t === 'integer') return parseInt(_numSample(ml, 0), 10);
|
||||||
if (t === 'number') {
|
if (t === 'number') {
|
||||||
var ip = '123456';
|
var d = parseInt(decimals, 10);
|
||||||
if (ml && ml > 0 && ip.length > ml) ip = ip.substring(0, ml);
|
if (!(d > 0)) d = 3;
|
||||||
return parseFloat(ip + '.123');
|
return parseFloat(_numSample(ml, d));
|
||||||
}
|
}
|
||||||
if (t === 'boolean') return false;
|
if (t === 'boolean') return false;
|
||||||
var v = 'sample_' + (name || '');
|
var v = 'sample_' + (name || '');
|
||||||
@@ -1851,7 +1871,7 @@
|
|||||||
if (t === 'object') return _sampleObj(row.children || []);
|
if (t === 'object') return _sampleObj(row.children || []);
|
||||||
if (t === 'array') { var it = (row.itemsType && row.itemsType.value) || 'string'; return [it === 'object' ? _sampleObj(row.children || []) : _defScalar(it, (row.name && row.name.value) || 'item', '')]; }
|
if (t === 'array') { var it = (row.itemsType && row.itemsType.value) || 'string'; return [it === 'object' ? _sampleObj(row.children || []) : _defScalar(it, (row.name && row.name.value) || 'item', '')]; }
|
||||||
if (ex !== undefined && ex !== '') return _coerce(t, ex);
|
if (ex !== undefined && ex !== '') return _coerce(t, ex);
|
||||||
return _defScalar(t, (row.name && row.name.value) || '', row.maxLength && row.maxLength.value);
|
return _defScalar(t, (row.name && row.name.value) || '', row.maxLength && row.maxLength.value, row.decimals && row.decimals.value);
|
||||||
}
|
}
|
||||||
function _sampleObj(rows) { var o = {}; (rows || []).forEach(function (r) { if (r && r.name && r.name.value) o[r.name.value] = _sampleVal(r); }); return o; }
|
function _sampleObj(rows) { var o = {}; (rows || []).forEach(function (r) { if (r && r.name && r.name.value) o[r.name.value] = _sampleVal(r); }); return o; }
|
||||||
function ensureExamplesFromSchema(force) {
|
function ensureExamplesFromSchema(force) {
|
||||||
@@ -1897,7 +1917,7 @@
|
|||||||
if (r.children && r.children.length) fillSchemaExamples(r.children);
|
if (r.children && r.children.length) fillSchemaExamples(r.children);
|
||||||
} else {
|
} else {
|
||||||
r.example = r.example || { value: '', locked: false };
|
r.example = r.example || { value: '', locked: false };
|
||||||
r.example.value = String(_defScalar(t, r.name.value || '', r.maxLength && r.maxLength.value));
|
r.example.value = String(_defScalar(t, r.name.value || '', r.maxLength && r.maxLength.value, r.decimals && r.decimals.value));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ public class ApiSpecManService {
|
|||||||
String defaultValue = item.getLoutItemDefault();
|
String defaultValue = item.getLoutItemDefault();
|
||||||
String fieldName = item.getLoutItemName();
|
String fieldName = item.getLoutItemName();
|
||||||
|
|
||||||
boolean isInteger = isIntegerType(dataType);
|
boolean isInteger = isIntegerType(dataType, item.getLoutItemDecimal());
|
||||||
|
|
||||||
if (isNumericType(dataType)) {
|
if (isNumericType(dataType)) {
|
||||||
if (StringUtils.isNotEmpty(defaultValue)) {
|
if (StringUtils.isNotEmpty(defaultValue)) {
|
||||||
@@ -393,7 +393,7 @@ public class ApiSpecManService {
|
|||||||
private void addScalarToArray(ArrayNode arrayNode, LayoutItemUI item) {
|
private void addScalarToArray(ArrayNode arrayNode, LayoutItemUI item) {
|
||||||
String dataType = item.getLoutItemDataType();
|
String dataType = item.getLoutItemDataType();
|
||||||
String defaultValue = item.getLoutItemDefault();
|
String defaultValue = item.getLoutItemDefault();
|
||||||
boolean isInteger = isIntegerType(dataType);
|
boolean isInteger = isIntegerType(dataType, item.getLoutItemDecimal());
|
||||||
|
|
||||||
if (isNumericType(dataType)) {
|
if (isNumericType(dataType)) {
|
||||||
try {
|
try {
|
||||||
@@ -416,23 +416,29 @@ public class ApiSpecManService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isIntegerType(String dataType) {
|
/** BIGDECIMAL/DECIMAL 은 소수 자릿수가 0 이면 정수로 취급한다. */
|
||||||
|
private boolean isIntegerType(String dataType, int decimalLen) {
|
||||||
if (dataType == null) return false;
|
if (dataType == null) return false;
|
||||||
switch (dataType.toUpperCase()) {
|
switch (dataType.toUpperCase()) {
|
||||||
case "INTEGER":
|
case "INTEGER":
|
||||||
case "INT":
|
case "INT":
|
||||||
case "LONG":
|
case "LONG":
|
||||||
return true;
|
return true;
|
||||||
|
case "DECIMAL":
|
||||||
|
case "BIGDECIMAL":
|
||||||
|
return decimalLen <= 0;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNumericType(String dataType) {
|
private boolean isNumericType(String dataType) {
|
||||||
if (isIntegerType(dataType)) return true;
|
|
||||||
if (dataType == null) return false;
|
if (dataType == null) return false;
|
||||||
|
|
||||||
switch (dataType.toUpperCase()) {
|
switch (dataType.toUpperCase()) {
|
||||||
|
case "INTEGER":
|
||||||
|
case "INT":
|
||||||
|
case "LONG":
|
||||||
case "DECIMAL":
|
case "DECIMAL":
|
||||||
case "DOUBLE":
|
case "DOUBLE":
|
||||||
case "BIGDECIMAL":
|
case "BIGDECIMAL":
|
||||||
@@ -621,11 +627,7 @@ public class ApiSpecManService {
|
|||||||
parameter.put("required", false); // 기본값으로 false 설정, 필요시 true로 변경 가능
|
parameter.put("required", false); // 기본값으로 false 설정, 필요시 true로 변경 가능
|
||||||
|
|
||||||
ObjectNode schema = parameter.putObject("schema");
|
ObjectNode schema = parameter.putObject("schema");
|
||||||
schema.put("type", mapSwaggerType(item.getLoutItemDataType()));
|
putScalarSchema(schema, item);
|
||||||
int length = item.getLoutItemLength();
|
|
||||||
if (length > 0) {
|
|
||||||
schema.put("maxLength", item.getLoutItemLength());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -651,11 +653,7 @@ public class ApiSpecManService {
|
|||||||
parameter.put("required", false); // 기본값 false, 필요시 사용자가 변경
|
parameter.put("required", false); // 기본값 false, 필요시 사용자가 변경
|
||||||
|
|
||||||
ObjectNode schema = parameter.putObject("schema");
|
ObjectNode schema = parameter.putObject("schema");
|
||||||
schema.put("type", mapSwaggerType(item.getLoutItemDataType()));
|
putScalarSchema(schema, item);
|
||||||
int length = item.getLoutItemLength();
|
|
||||||
if (length > 0) {
|
|
||||||
schema.put("maxLength", length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,11 +663,7 @@ public class ApiSpecManService {
|
|||||||
ObjectNode header = headers.putObject(item.getLoutItemName());
|
ObjectNode header = headers.putObject(item.getLoutItemName());
|
||||||
header.put("description", item.getLoutItemDesc());
|
header.put("description", item.getLoutItemDesc());
|
||||||
ObjectNode schema = header.putObject("schema");
|
ObjectNode schema = header.putObject("schema");
|
||||||
schema.put("type", mapSwaggerType(item.getLoutItemDataType()));
|
putScalarSchema(schema, item);
|
||||||
int length = item.getLoutItemLength();
|
|
||||||
if (length > 0) {
|
|
||||||
schema.put("maxLength", item.getLoutItemLength());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -695,14 +689,10 @@ public class ApiSpecManService {
|
|||||||
switch (item.getLoutItemType().toUpperCase()) {
|
switch (item.getLoutItemType().toUpperCase()) {
|
||||||
case "FIELD":
|
case "FIELD":
|
||||||
ObjectNode fieldSchema = parentNode.putObject(item.getLoutItemName());
|
ObjectNode fieldSchema = parentNode.putObject(item.getLoutItemName());
|
||||||
fieldSchema.put("type", mapSwaggerType(item.getLoutItemDataType()));
|
putScalarSchema(fieldSchema, item);
|
||||||
if (StringUtils.isNotEmpty(item.getLoutItemDesc())) {
|
if (StringUtils.isNotEmpty(item.getLoutItemDesc())) {
|
||||||
fieldSchema.put("description", item.getLoutItemDesc());
|
fieldSchema.put("description", item.getLoutItemDesc());
|
||||||
}
|
}
|
||||||
int length = item.getLoutItemLength();
|
|
||||||
if (length > 0) {
|
|
||||||
fieldSchema.put("maxLength", item.getLoutItemLength());
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "GROUP":
|
case "GROUP":
|
||||||
@@ -730,14 +720,18 @@ public class ApiSpecManService {
|
|||||||
arrItems.put("type", "object");
|
arrItems.put("type", "object");
|
||||||
depthMap.put(item.getLoutItemDepth(), arrItems.putObject("properties"));
|
depthMap.put(item.getLoutItemDepth(), arrItems.putObject("properties"));
|
||||||
} else {
|
} else {
|
||||||
arrItems.put("type", mapSwaggerType(item.getLoutItemDataType()));
|
putScalarSchema(arrItems, item);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String mapSwaggerType(String dataType) {
|
/**
|
||||||
|
* 레이아웃 데이터타입 → OpenAPI type.
|
||||||
|
* <p>BIGDECIMAL/DECIMAL 은 소수 자릿수(decimalLen)가 0 이면 정수로 취급한다.
|
||||||
|
*/
|
||||||
|
private String mapSwaggerType(String dataType, int decimalLen) {
|
||||||
if (dataType == null) return "string";
|
if (dataType == null) return "string";
|
||||||
|
|
||||||
switch (dataType.toUpperCase()) {
|
switch (dataType.toUpperCase()) {
|
||||||
@@ -747,8 +741,9 @@ public class ApiSpecManService {
|
|||||||
case "LONG":
|
case "LONG":
|
||||||
return "integer";
|
return "integer";
|
||||||
case "DECIMAL":
|
case "DECIMAL":
|
||||||
case "DOUBLE":
|
|
||||||
case "BIGDECIMAL":
|
case "BIGDECIMAL":
|
||||||
|
return decimalLen > 0 ? "number" : "integer";
|
||||||
|
case "DOUBLE":
|
||||||
return "number";
|
return "number";
|
||||||
case "BOOLEAN":
|
case "BOOLEAN":
|
||||||
return "boolean";
|
return "boolean";
|
||||||
@@ -757,6 +752,23 @@ public class ApiSpecManService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 스칼라 FIELD 의 스키마(type/maxLength/소수 자릿수)를 채운다.
|
||||||
|
* <p>길이(maxLength)는 레이아웃 길이 그대로이며, 소수가 있는 숫자의 예제값은
|
||||||
|
* 소수점(.)을 포함해 이 길이를 넘지 않도록 프론트에서 생성한다(예: 길이 9/소수 5 → 123.45678).
|
||||||
|
*/
|
||||||
|
private void putScalarSchema(ObjectNode schema, LayoutItemUI item) {
|
||||||
|
String type = mapSwaggerType(item.getLoutItemDataType(), item.getLoutItemDecimal());
|
||||||
|
schema.put("type", type);
|
||||||
|
int length = item.getLoutItemLength();
|
||||||
|
if (length > 0) {
|
||||||
|
schema.put("maxLength", length);
|
||||||
|
}
|
||||||
|
if ("number".equals(type) && item.getLoutItemDecimal() > 0) {
|
||||||
|
schema.put("x-djb-decimal", item.getLoutItemDecimal());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isRequestBodyRequired(String method) {
|
private boolean isRequestBodyRequired(String method) {
|
||||||
if (method == null) return false;
|
if (method == null) return false;
|
||||||
return "POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method);
|
return "POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method);
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ public class DjbApiSpecLayoutMergeService {
|
|||||||
r.put("desc", it.getLoutItemDesc());
|
r.put("desc", it.getLoutItemDesc());
|
||||||
r.put("itemType", it.getLoutItemType()); // FIELD / GROUP / GRID
|
r.put("itemType", it.getLoutItemType()); // FIELD / GROUP / GRID
|
||||||
r.put("dataType", dataType);
|
r.put("dataType", dataType);
|
||||||
r.put("category", sampleGenerator.categoryOf(dataType));
|
r.put("category", sampleGenerator.categoryOf(dataType, dec));
|
||||||
r.put("length", len);
|
r.put("length", len);
|
||||||
r.put("decimal", dec);
|
r.put("decimal", dec);
|
||||||
r.put("depth", it.getLoutItemDepth());
|
r.put("depth", it.getLoutItemDepth());
|
||||||
|
|||||||
+59
-23
@@ -4,19 +4,25 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* D10 예제값 자동 생성 규칙.
|
* D10 예제값 자동 생성 규칙. (프론트 app.js 의 _defScalar/_numSample 와 동일 규칙)
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>string → {@code sample_} + 항목명. 최대길이 초과 시 left-cut(앞에서 자름).</li>
|
* <li>string → {@code sample_} + 항목명. 최대길이 초과 시 left-cut(앞에서 자름).</li>
|
||||||
* <li>integer → {@code 1}</li>
|
* <li>integer → {@code 123456} (길이 지정 시 그 길이에 맞춰 자릿수 축소)</li>
|
||||||
* <li>number → {@code 1.1} (소수 자릿수 지정 시 {@code 1.1000} 형태)</li>
|
* <li>number → 소수점(.)을 포함한 전체 길이 기준. 길이 9 / 소수 5 → {@code 123.45678}</li>
|
||||||
* <li>boolean → {@code false}</li>
|
* <li>boolean → {@code false}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
* <p>BIGDECIMAL/DECIMAL 은 소수 자릿수가 0 이면 정수(integer)로 분류한다.
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class DjbApiSpecSampleGenerator {
|
public class DjbApiSpecSampleGenerator {
|
||||||
|
|
||||||
/** 원시 데이터타입(레이아웃 값)을 OpenAPI 계열 카테고리로 분류. */
|
/**
|
||||||
public String categoryOf(String rawDataType) {
|
* 원시 데이터타입(레이아웃 값)을 OpenAPI 계열 카테고리로 분류.
|
||||||
|
*
|
||||||
|
* @param rawDataType 레이아웃 데이터타입(원시)
|
||||||
|
* @param decimalLen 소수 자릿수. decimal 계열에서 0 이면 정수로 본다.
|
||||||
|
*/
|
||||||
|
public String categoryOf(String rawDataType, int decimalLen) {
|
||||||
if (rawDataType == null) {
|
if (rawDataType == null) {
|
||||||
return "string";
|
return "string";
|
||||||
}
|
}
|
||||||
@@ -24,18 +30,22 @@ public class DjbApiSpecSampleGenerator {
|
|||||||
if (t.contains("bool")) {
|
if (t.contains("bool")) {
|
||||||
return "boolean";
|
return "boolean";
|
||||||
}
|
}
|
||||||
if (t.contains("decimal") || t.contains("double") || t.contains("float") || t.contains("number")) {
|
|
||||||
return "number";
|
|
||||||
}
|
|
||||||
if (t.contains("int") || t.contains("long")) {
|
|
||||||
return "integer";
|
|
||||||
}
|
|
||||||
if (t.contains("object") || t.contains("group")) {
|
if (t.contains("object") || t.contains("group")) {
|
||||||
return "object";
|
return "object";
|
||||||
}
|
}
|
||||||
if (t.contains("array") || t.contains("grid") || t.contains("list")) {
|
if (t.contains("array") || t.contains("grid") || t.contains("list")) {
|
||||||
return "array";
|
return "array";
|
||||||
}
|
}
|
||||||
|
if (t.contains("decimal")) {
|
||||||
|
// BigDecimal/Decimal: 소수 자릿수 0 = 정수
|
||||||
|
return decimalLen > 0 ? "number" : "integer";
|
||||||
|
}
|
||||||
|
if (t.contains("double") || t.contains("float") || t.contains("number")) {
|
||||||
|
return "number";
|
||||||
|
}
|
||||||
|
if (t.contains("int") || t.contains("long")) {
|
||||||
|
return "integer";
|
||||||
|
}
|
||||||
return "string";
|
return "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,22 +53,15 @@ public class DjbApiSpecSampleGenerator {
|
|||||||
* 예제값 생성.
|
* 예제값 생성.
|
||||||
* @param rawDataType 레이아웃 데이터타입(원시)
|
* @param rawDataType 레이아웃 데이터타입(원시)
|
||||||
* @param fieldName 항목명
|
* @param fieldName 항목명
|
||||||
* @param maxLen 최대 길이(0/음수면 무제한)
|
* @param maxLen 최대 길이(0/음수면 무제한). 숫자는 소수점(.)을 포함한 문자열 길이 기준.
|
||||||
* @param decimalLen 소수 자릿수(0이면 미적용)
|
* @param decimalLen 소수 자릿수(0이면 정수)
|
||||||
*/
|
*/
|
||||||
public String exampleFor(String rawDataType, String fieldName, int maxLen, int decimalLen) {
|
public String exampleFor(String rawDataType, String fieldName, int maxLen, int decimalLen) {
|
||||||
switch (categoryOf(rawDataType)) {
|
switch (categoryOf(rawDataType, decimalLen)) {
|
||||||
case "integer":
|
case "integer":
|
||||||
return "1";
|
return numberSample(maxLen, 0);
|
||||||
case "number":
|
case "number":
|
||||||
if (decimalLen > 0) {
|
return numberSample(maxLen, decimalLen > 0 ? decimalLen : 3);
|
||||||
StringBuilder sb = new StringBuilder("1.");
|
|
||||||
for (int i = 0; i < decimalLen; i++) {
|
|
||||||
sb.append(i == 0 ? '1' : '0');
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
return "1.1";
|
|
||||||
case "boolean":
|
case "boolean":
|
||||||
return "false";
|
return "false";
|
||||||
case "object":
|
case "object":
|
||||||
@@ -72,4 +75,37 @@ public class DjbApiSpecSampleGenerator {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 숫자 예제값. 길이는 소수점(.)까지 포함한 문자열 전체 길이로 계산한다.
|
||||||
|
* <p>예) 길이 9 / 소수 5 → {@code 123.45678} (정수부 3 + '.' 1 + 소수부 5 = 9자).
|
||||||
|
* 길이가 소수부+2 보다 짧으면 정수부 1자리를 확보하고 소수부를 줄인다.
|
||||||
|
* 길이 미지정이면 정수부 6자리를 사용한다.
|
||||||
|
*/
|
||||||
|
private String numberSample(int maxLen, int decimalLen) {
|
||||||
|
if (decimalLen <= 0) {
|
||||||
|
return digits(0, maxLen > 0 ? Math.min(maxLen, 6) : 6);
|
||||||
|
}
|
||||||
|
int dec = decimalLen;
|
||||||
|
int intLen;
|
||||||
|
if (maxLen > 0) {
|
||||||
|
intLen = maxLen - dec - 1; // '.' 1자리 포함
|
||||||
|
if (intLen < 1) {
|
||||||
|
intLen = 1;
|
||||||
|
dec = Math.max(1, maxLen - 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
intLen = 6;
|
||||||
|
}
|
||||||
|
return digits(0, intLen) + "." + digits(intLen, dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** start 위치부터 1~9 를 순환하는 자릿수 문자열('123456789123...'). */
|
||||||
|
private String digits(int start, int count) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
sb.append((char) ('1' + ((start + i) % 9)));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user