Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.s1.xsdutils.XSD2ObjectSchema Maven / Gradle / Ivy
package org.s1.xsdutils;
import org.apache.xerces.impl.xs.XSComplexTypeDecl;
import org.apache.xerces.impl.xs.XSElementDecl;
import org.apache.xerces.impl.xs.XSParticleDecl;
import org.apache.xerces.xs.*;
import org.s1.format.xml.XMLFormat;
import org.s1.format.xml.XMLFormatException;
import org.s1.misc.Closure;
import org.s1.objects.ObjectPath;
import org.s1.objects.Objects;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.util.List;
import java.util.Map;
/**
* s1v2
* User: GPykhov
* Date: 16.01.14
* Time: 20:07
*/
public class XSD2ObjectSchema {
private static XSTypeDefinition getBaseSimpleType(XSTypeDefinition type){
while(true){
if("anySimpleType".equals(type.getName()) || "anySimpleType".equals(type.getBaseType().getName())){
break;
}
type = type.getBaseType();
}
return type;
}
private static String getAnnotation(XSAnnotation a){
return getAnnotation(a,null);
}
private static String getAnnotation(XSAnnotation a, String path){
if(Objects.isNullOrEmpty(path))
path = "documentation";
try {
return XMLFormat.get(XMLFormat.fromString(a.getAnnotationString()).getDocumentElement(), path, null, "");
} catch (Throwable e) {
}
return null;
}
private static Map xstypeToAttrMap(XSTypeDefinition type){
Map attr = Objects.newHashMap();
if(type instanceof XSComplexTypeDecl){
//map or ref
if(type.getAnonymous()){
//map
attr.put("type","Map");
attr.put("attributes",Objects.newArrayList());
}else{
//ref
attr.put("type","#"+type.getName());
}
}else{
//simple type
XSTypeDefinition st = getBaseSimpleType(type);
setAttrWithXSDType(attr,st.getName());
}
return attr;
}
private static void setAttrWithXSDType(Map attr, String type){
if(attr.get("hint")==null)
attr.put("hint",Objects.newHashMap());
if(Objects.newArrayList("string","anyURI","normalizedString","anySimpleType").contains(type)){
attr.put("type","String");
}else if(Objects.newArrayList("int","integer","nonNegativeInteger","nonPositiveInteger","short","unsignedInt","unsignedShort","unsignedByte","byte").contains(type)){
attr.put("type","Integer");
}else if(Objects.newArrayList("long","unsignedLong").contains(type)){
attr.put("type","Long");
}else if("float".equals(type)){
attr.put("type","Float");
}else if("double".equals(type)){
attr.put("type","Double");
}else if("decimal".equals(type)){
attr.put("type","BigDecimal");
}else if("boolean".equals(type)){
attr.put("type","Boolean");
}else if("date".equals(type)){
attr.put("type","Date");
}else if("dateTime".equals(type)){
attr.put("type","Date");
Objects.set(attr,"hint.type","dateSecond");
}
}
private static final int MAX_LABEL_LENGTH = 100;
/**
*
* @param xsd
* @return
*/
public static Map toSchemaMap(Document xsd){
return toSchemaMap(xsd.getDocumentElement());
}
/**
*
* @param xsd
* @return
*/
public static Map toSchemaMap(Element xsd){
final List> attributes = Objects.newArrayList();
final List> types = Objects.newArrayList();
final Map schema = Objects.newHashMap("attributes",attributes,"types",types);
final Map attrs = Objects.newHashMap();
//def attrs = [:] as TreeMap;
XSDIterator.iterateXSD(xsd, new Closure() {
@Override
public Object call(XSDIterator.XSDIterateBean input) {
Map attr = null;
if (input.getObject() instanceof XSParticleDecl) {
XSTerm term = input.getParticle().getTerm();
if (term instanceof XSElementDecl) {
attr = xstypeToAttrMap(((XSElementDecl) term).getTypeDefinition());
attr.put("name", term.getName());
attr.put("appearance", input.getParticle().getMinOccurs() == 0 ? "normal" : "required");
String l = getAnnotation(((XSElementDecl) term).getAnnotation());
if (!Objects.isNullOrEmpty(l)) {
if (l.length() < MAX_LABEL_LENGTH) {
attr.put("label", l);
} else {
attr.put("label", l.substring(0, MAX_LABEL_LENGTH) + "...");
attr.put("description", l);
}
} else {
attr.put("label", attr.get("name"));
}
if (input.getParticle().getMaxOccursUnbounded() || input.getParticle().getMaxOccurs() > 1) {
//list
attr = Objects.newHashMap("type", "List", "name", attr.get("name"), "label", attr.get("label"),
"description", attr.get("description"),
"element", attr,
"appearance", "required", "default", Objects.newArrayList());
((Map) attr.get("element")).remove("name");
((Map) attr.get("element")).remove("label");
((Map) attr.get("element")).remove("description");
if (input.getParticle().getMinOccurs() > 0)
attr.put("min", input.getParticle().getMinOccurs());
if (!input.getParticle().getMaxOccursUnbounded())
attr.put("max", input.getParticle().getMaxOccurs());
} else if (((XSElementDecl) term).getTypeDefinition() instanceof XSComplexTypeDecl) {
//map or ref
attr.put("appearance", "required");
attr.put("default", Objects.newHashMap());
} else {
//simple type
}
} else if (term instanceof XSModelGroup) {
}
} else if (input.getObject() instanceof XSTypeDefinition) {
//global type
if (input.getTypeDefinition() instanceof XSComplexTypeDecl) {
Map tp = xstypeToAttrMap(input.getTypeDefinition());
tp.put("name", input.getTypeDefinition().getName());
tp.remove("type");
tp.put("attributes", Objects.newArrayList());
types.add(tp);
}
} else if (input.getObject() instanceof XSElementDecl) {
//root elements
attr = xstypeToAttrMap(input.getElementDeclaration().getTypeDefinition());
attr.put("name", input.getElementDeclaration().getName());
attr.put("appearance", "normal");
String l = getAnnotation(input.getElementDeclaration().getAnnotation());
if (!Objects.isNullOrEmpty(l)) {
if (l.length() < MAX_LABEL_LENGTH) {
attr.put("label", l);
} else {
attr.put("label", l.substring(0, MAX_LABEL_LENGTH) + "...");
attr.put("description", l);
}
} else {
attr.put("label", attr.get("name"));
}
if (input.getElementDeclaration().getTypeDefinition() instanceof XSComplexTypeDecl) {
//map or ref
attr.put("appearance", "required");
attr.put("default", Objects.newHashMap());
} else {
//simple type
}
} if (input.getObject() instanceof XSAttributeUse) {
//simple type
attr = xstypeToAttrMap(input.getAttributeUse().getAttrDeclaration().getTypeDefinition());
attr.put("name", "@" + input.getAttributeUse().getAttrDeclaration().getName());
attr.put("appearance", input.getAttributeUse().getRequired() ? "required" : "normal");
String l = getAnnotation(input.getAttributeUse().getAttrDeclaration().getAnnotation());
if (!Objects.isNullOrEmpty(l)) {
if (l.length() < MAX_LABEL_LENGTH) {
attr.put("label", l);
} else {
attr.put("label", l.substring(0, MAX_LABEL_LENGTH) + "...");
attr.put("description", l);
}
} else {
attr.put("label", attr.get("name"));
}
}
//add attr
if (attr != null) {
attrs.put(input.getPath(), attr);
}
return null;
}
});
//create tree
for(Map.Entry it:attrs.entrySet()){
Map a = getParentAttrFromSchema(schema,it.getKey());
if(a==null){
a = schema;
}
//println(it.key+":::"+a+":::"+it.value);
if(!a.containsKey("type") || "Map".equals(a.get("type"))){
((List)a.get("attributes")).add(it.getValue());
}else if("List".equals(a.get("type")) && "Map".equals(Objects.get(a, "element.type"))){
Objects.get(List.class,a,"element.attributes").add(it.getValue());
}
}
return schema;
}
/**
*
* @param schema
* @param path
* @return
*/
private static Map getParentAttrFromSchema(Map schema, String path){
Map a = null;
boolean isType = false;
if(path.startsWith("#")){
path = path.substring(1);
isType = true;
}
final String [] p = ObjectPath.tokenizePath(path);
/*path.replace("&","&").replace("\\.","˙");
def p = path.split("\\.");
p.eachWithIndex { String entry, int i ->
p[i] = p[i].replace("˙",".").replace("&","&");
}*/
if(isType){
//type
a = Objects.find((List>)schema.get("types"),new Closure, Boolean>() {
@Override
public Boolean call(Map input) {
return input.get("name").equals(p[0]);
}
});
}else{
//attr
a = Objects.find((List>)schema.get("attributes"),new Closure, Boolean>() {
@Override
public Boolean call(Map input) {
return input.get("name").equals(p[0]);
}
});
}
for(int i=1;i>)a.get("attributes"),new Closure, Boolean>() {
@Override
public Boolean call(Map input) {
return input.get("name").equals(p[index]);
}
});
}else if("List".equals(a.get("type")) && "Map".equals(Objects.get(a,"element.type"))){
a = Objects.find((List>)Objects.get(a,"element.attributes"),new Closure, Boolean>() {
@Override
public Boolean call(Map input) {
return input.get("name").equals(p[index]);
}
});
}else{
a = null;
}
}
return a;
}
}