package org.rakam.collection; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.netty.handler.codec.http.HttpResponseStatus; import org.rakam.server.http.annotations.ApiParam; import org.rakam.util.RakamException; import org.rakam.util.ValidationUtil; import java.util.Locale; public class SchemaField { private final String name; private final FieldType type; @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) private final Boolean unique; @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) private final String description; @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) private final String descriptiveName; @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) private final String category; @JsonCreator public SchemaField(@ApiParam("name") String name, @ApiParam("type") FieldType type, @ApiParam(value = "unique", required = false) Boolean unique, @ApiParam(value = "descriptiveName", required = false) String descriptiveName, @ApiParam(value = "description", required = false) String description, @ApiParam(value = "category", required = false) String category) { this.name = stripName(ValidationUtil.checkNotNull(name, "name"), "field name"); this.type = ValidationUtil.checkNotNull(type, "type"); this.unique = unique; this.descriptiveName = descriptiveName; this.description = description; this.category = category; if (this.name.isEmpty()) { throw new RakamException(String.format("Field name (%s) can't be empty string", this.name), HttpResponseStatus.BAD_REQUEST); } } public static String stripName(String name, String type) { if(name.isEmpty()) { throw new RakamException(type+" is empty", HttpResponseStatus.BAD_REQUEST); } StringBuilder builder = new StringBuilder(name.length()); for (int i = 0; i < name.length(); i++) { char charAt = name.charAt(i); if (charAt == '"' || (i == 0 && charAt == ' ')) { continue; } if (Character.isUpperCase(charAt)) { if (i > 0) { if (Character.isLowerCase(name.charAt(i - 1))) { builder.append("_"); } } builder.append(Character.toLowerCase(charAt)); } else { builder.append(charAt); } } if(builder.length() == 0) { throw new RakamException("Invalid "+type+": "+name, HttpResponseStatus.BAD_REQUEST); } int lastIdx = builder.length() - 1; if(builder.charAt(lastIdx) == ' ') { builder.deleteCharAt(lastIdx); } return builder.toString(); } public SchemaField(String name, FieldType type) { this(name, type, null, null, null, null); } @JsonProperty public String getName() { return name; } @JsonProperty public FieldType getType() { return type; } @JsonProperty public Boolean isUnique() { return unique; } public String getCategory() { return category; } @JsonProperty public String getDescriptiveName() { if (descriptiveName == null) { String replace = name.replace("_", " ").trim(); return Character.toUpperCase(replace.charAt(0)) + replace.substring(1); } return descriptiveName; } @JsonProperty @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) public String getDescription() { return description; } @Override public String toString() { return "SchemaField{" + "name='" + name + '\'' + ", type=" + type + '}'; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof SchemaField)) { return false; } SchemaField that = (SchemaField) o; if (!name.equals(that.name)) { return false; } if (type != that.type) { return false; } return true; } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + type.hashCode(); return result; } }