
org.tinystruct.data.component.Builder Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2017 James Mover Zhou
*
* 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.tinystruct.data.component;
import org.tinystruct.ApplicationException;
import org.tinystruct.system.util.StringUtilities;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Logger;
public class Builder extends HashMap implements Struct, Serializable {
private static final String QUOTE = "\"";
private static final long serialVersionUID = 3484789992424316230L;
private boolean log = false;
private static final Logger logger = Logger.getLogger(Builder.class.getName());
public Builder() {
}
public String toString() {
StringBuilder buffer = new StringBuilder();
Set keys = this.keySet();
for (String key : keys) {
Object value = this.get(key);
if (value instanceof String || value instanceof StringBuffer || value instanceof StringBuilder)
buffer.append(QUOTE).append(key).append(QUOTE).append(":").append(
QUOTE + StringUtilities.escape(value.toString()) + QUOTE);
else
buffer.append(QUOTE).append(key).append(QUOTE).append(":").append(value);
buffer.append(",");
}
if (buffer.length() > 0)
buffer.setLength(buffer.length() - 1);
return "{" + buffer.toString() + "}";
}
/**
* Parse the resource.
* Format:{"Name":"Mover","Birthday":"1982-03-20","Ability":{"Item1":"Music"
* ,"Item2","Java"}}
*
* @param resource JSON string
* @throws ApplicationException application exception
*/
public void parse(String resource) throws ApplicationException {
// 默认相信任何一个被传入的都是合法的字符串
resource = resource.trim();
if (!resource.startsWith("{") || !resource.endsWith("}")) {
throw new ApplicationException("Invalid data format!");
}
if (resource.startsWith("{")) {
if (log) logger.info("待处理:{}" + resource);
// 查找关闭位置
this.closedPosition = this.seekPosition(resource);
// 获得传入的实体对象里{key:value,key:value,...key:value},{key:value,key:value,...key:value}序列
// 脱去传入的实体对象外壳 key:value,key:value,...key:value 序列
String values = resource.substring(1, closedPosition - 1);
if (log) logger.info("已脱壳:" + values);
this.parseValue(values);
}
}
private int closedPosition = 0;
public int getClosedPosition() {
return closedPosition;
}
public void setClosedPosition(int closedPosition) {
this.closedPosition = closedPosition;
}
private void parseValue(String value) throws ApplicationException {
if (log) logger.info("待分析:" + value);
value = value.trim();
if (value.startsWith(QUOTE)) {
// 处理传入的实体对象外壳 "key":value,"key":"value",..."key":value 序列
int COLON_POSITION = value.indexOf(':'), start = COLON_POSITION + 1;
String keyName = value.substring(1, COLON_POSITION - 1);
if (log) logger.info("取键值:" + keyName);
String $value = value.substring(start).trim();
if (log) logger.info("分析值:" + $value);
Object keyValue = null;
if ($value.startsWith(QUOTE)) {
if (log) logger.info("提取值:" + $value);
int $end = this.next($value, '"');
keyValue = $value.substring(1, $end - 1).trim();
if ($end + 1 < $value.length()) {
$value = $value.substring($end + ",".length());
this.parseValue($value);
}
} else if ($value.indexOf('{') == 0) {
if (log) logger.info("遇实体:" + $value);
int closedPosition = this.seekPosition($value);
// 获得传入的实体对象里{key:value,key:value,...key:value},{key:value,key:value,...key:value}序列
// 脱去传入的实体对象外壳 key:value,key:value,...key:value 序列
String _$value = $value.substring(0, closedPosition);
if (log) logger.info("分实体:" + _$value);
Builder builder = new Builder();
builder.parse(_$value);
keyValue = builder;
if (closedPosition < $value.length()) {
_$value = $value.substring(closedPosition + ",".length());
if (log) logger.info("分实体:" + _$value);
this.parseValue(_$value);
}
} else if ($value.indexOf('[') == 0) {
Builders builders = new Builders();
if (log) logger.info($value);
builders.parse($value);
keyValue = builders;
} else {
if ($value.indexOf(',') != -1) {
keyValue = $value.substring(0, $value.indexOf(','));
$value = $value.substring($value.indexOf(',') + 1);
this.parseValue($value);
} else {
keyValue = $value;
}
}
this.put(keyName, keyValue);
}
}
private int seekPosition(String value) {
char[] charray = value.toCharArray();
int i = 0, n = 0;
int position = charray.length;
while (i < position) {
char c = charray[i];
if (c == '{') {
if (i - 1 >= 0 && charray[i - 1] == '\\') {
;
} else
n++;
} else if (c == '}') {
if (i - 1 >= 0 && charray[i - 1] == '\\') {
;
} else
n--;
}
i++;
if (n == 0)
position = i;
}
return position;
}
private int next(String value, char begin) {
char[] charray = value.toCharArray();
int i = 0, n = 0, position = charray.length;
while (i < position) {
char c = charray[i];
if (c == begin) {
if (i - 1 >= 0 && charray[i - 1] == '\\') {
;
} else
n++;
}
i++;
if (n == 2)
position = i;
}
return position;
}
public Row toData() {
Row row = new Row();
Field field = new Field();
Set keySet = this.keySet();
for (String key : keySet) {
Object value = this.get(key);
FieldInfo info = new FieldInfo();
info.set("name", key);
info.set("value", value);
field.append(key, info);
}
row.append(field);
return row;
}
public void saveAsFile(File file) throws ApplicationException {
try(PrintWriter writer = new PrintWriter(file)) {
writer.write(this.toString());
} catch (FileNotFoundException e) {
throw new ApplicationException(e.getMessage(), e);
}
}
@Override
public int size() {
return this.keySet().size();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy