Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* ************************************************************************
  #
  #  DivConq
  #
  #  http://divconq.com/
  #
  #  Copyright:
  #    Copyright 2014 eTimeline, LLC. All rights reserved.
  #
 #  License:
 #    See the license.txt file in the project's top-level directory for details.
 #
 #  Authors:
 #    * Andy White
 #
 ************************************************************************ */
 package divconq.schema;
 
 import java.util.List;
 
 
 public class DataType {
 	enum DataKind {
 		Scalar(1),
 		List(2),
 		Record(3);
 	    
 	    private int code;
 
 	    private DataKind(int c) {
 	       = c;
 	    }
 
 	    public int getCode() {
 	      return ;
 	    }
 	}
 
 	protected Schema schema = null;
 	protected String id = null;
 	protected DataKind kind = null;
 	protected boolean compiled = false;
 	protected XElement definition = null;	
 	protected List<XElementxtraDefinitions = null;  //new ArrayList<XElement>();
 	
 	// for record
 	protected HashMap<String,Fieldfields = null
 	protected boolean anyRec = false;
 	
 	// for list
 	protected TypeOptionsList items = null;
 	protected int minItems = 0;
 	protected int maxItems = 0;
 	
 	// for scalar
 	protected CoreType core = null;
 
 	public String getId() {
 		return this.;
 	}
 	
 	public boolean isAnyRecord() {
 		return this.;
 	}
 	
 	public DataType(Schema schema) {
 		this. = schema;
 	}
 
 	public RecordStruct toJsonDef(int lvl) {
 		if (lvl == 0) {
 			RecordStruct def = new RecordStruct();
 			def.setField("Kind".);
 			def.setField("CoreType"new CoreType(.).toJsonDef());
 			return def;
 		}
 		
 		RecordStruct def = new RecordStruct();
 		
 		if (StringUtil.isNotEmpty(this.))
 			def.setField("Id"this.);
 		
 		def.setField("Kind"this..getCode());
 		
 		if (this. == .) {
			if (this.)
				def.setField("AnyRec"true);
			ListStruct fields = new ListStruct();
			for (Field fld : this..values()) 
				fields.addItem(fld.toJsonDef(lvl - 1));
			def.setField("Fields"fields);
		}
		else if (this. == .) {
			if (this. > 0)
				def.setField("MaxItems"this.);
			if (this. > 0)
				def.setField("MinItems"this.);
			if (this. != null)
				def.setField("Items"this..toJsonDef(lvl - 1));
		}
		else if (this. == .) {
			if (this. != null)
				def.setField("CoreType"this..toJsonDef());
		}
		return def;
	}
	public Collection<FieldgetFields() {
		if (this. == null)
			return new ArrayList<Field>();
		return this..values();
	}
	public Field getField(String name) {
		if (this. == null)
			return null;
		return this..get(name);
	}
	public void load(OperationResult orXElement dtel) {
		if (this. != null) {
			if (this. == null)
			this..add(dtel);			
			return;
		}
		this. = dtel;
		String elname = dtel.getName();
		if ("Record".equals(elname) || "Table".equals(elname) || "Request".equals(elname) || "Response".equals(elname) || "RecRequest".equals(elname) || "RecResponse".equals(elname)) 
		else if ("List".equals(elname) || "ListRequest".equals(elname) || "ListResponse".equals(elname)) 
			this. = .;
		else 
		this. = dtel.getAttribute("Id");
	}
	public void compile(OperationResult mr) {
		if (this.)
			return;
		// to prevent recursion issues, mark compiled immediately
		this. = true;
		if (this. == .)
			this.compileRecord(mr);
		else if (this. == .)
			this.compileList(mr);
		else
			this.compileScalar(mr);
	}
	protected void compileRecord(OperationResult mr) {
		List<Stringinhlist = new ArrayList<String>();
		if ("True".equals(this..getAttribute("Any")))
			this. = true;
		String inherits = this..getAttribute("Inherits");
		if (StringUtil.isNotEmpty(inherits)) {
			String[] ilist = inherits.split(",");
			for (int i = 0; i < ilist.lengthi++)
				inhlist.add(ilist[i]);
		}		
		List<DataTypeinheritTypes = new ArrayList<DataType>();
		for (String iname : inhlist) {
			DataType dtype = this...getType(iname);
			if (dtype == null) {
				mr.errorTr(413, iname);
				continue;
			}
			dtype.compile(mr);
			inheritTypes.add(dtype);
		}
		this. = new HashMap<String,Field>();
		for (XElement fel : this..selectAll("Field")) {
			Field f = new Field(this.);
			f.compile(felmr);
			this..put(f.namef);
		}
		if (this. != null) {
			for (XElement el : this.) {
				for (XElement fel : el.selectAll("Field")) {
					Field f = new Field(this.);
					f.compile(felmr);
					this..put(f.namef);
				}
			}
		}
		for (DataType dt : inheritTypes) {
			for (Field fld : dt.getFields()) {
				if (!this..containsKey(fld.name))
					this..put(fld.namefld);
			}
		}
	}
	protected void compileList(OperationResult mr) {
		this. = new TypeOptionsList(this.);		
		this..compile(this.mr);
		if (this..hasAttribute("MinCount"))
			this. = (int)StringUtil.parseInt(this..getAttribute("MinCount"), 0);
		if (this..hasAttribute("MaxCount"))
			this. = (int)StringUtil.parseInt(this..getAttribute("MaxCount"), 0);
	}
	protected void compileScalar(OperationResult mr) {
		this. = new CoreType(this.);
		this..compile(this.mr);
	}
	// don't call this with data == null from a field if field required - required means "not null" so put the error in
	public boolean match(Object dataOperationResult mr) {
		this.compile(mr);
		if (this. == .) {
			if (data instanceof RecordStruct)
				return this.matchRecord((RecordStruct)datamr);
			return false;
		}
		if (this. == .) {
			if (data instanceof RecordStruct)
				return this.matchList((RecordStruct)datamr);
			return false;
		}
		return this.matchScalar(datamr);
	}
	protected boolean matchRecord(RecordStruct dataOperationResult mr) {
		if (this. != null) {
			// match only if all required fields are present 
			for (Field fld : this..values()) {
				if ((fld.required == .) && !data.hasField(fld.name))
					return false;
				if ((fld.required == .) && data.hasField(fld.name) && data.isFieldEmpty(fld.name))
					return false;
			}
			return true;
		}
		// this is an exception to the rule, there is no "non-null" state to return from this method
		return this.;
	}
	protected boolean matchList(CompositeStruct dataOperationResult mr) {
		return true;		
	}
	protected boolean matchScalar(Object dataOperationResult mr) {
		if (this. == null
			return false;
		return this..match(datamr);
	}
	// don't call this with data == null from a field if field required - required means "not null" so put the error in
	// returns true only if there was a non-null value present that conforms to the expected structure (record, list or scalar) 
	// null values that do not conform should not cause an false
	public boolean validate(Struct dataOperationResult mr) {
		if (data == null)
			return false;
		this.compile(mr);
		if (this. == .) {
			if (data instanceof ICompositeBuilder)
				data = ((ICompositeBuilder)data).toLocal();			// TODO may be a source of a major inefficiency - may need to have configuration around it...
			if (data instanceof RecordStruct)
				return this.validateRecord((RecordStruct)datamr);
			mr.errorTr(414, data);
			return false;
		}
		if (this. == .) {
			if (data instanceof ListStruct)
				return this.validateList((ListStruct)datamr);
			mr.errorTr(415, data);		
			return false;
		}
		return this.validateScalar(datamr);
	}
	protected boolean validateRecord(RecordStruct dataOperationResult mr) {
		if (this. != null) {
			// handles all but the case where data holds a field not allowed 
			for (Field fld : this..values()) 
				fld.validate(data.hasField(fld.name), data.getField(fld.name), mr);
			if (!this.)
				for (FieldStruct fld : data.getFields()) {
					if (! this..containsKey(fld.getName()))
						mr.errorTr(419, fld.getName(), data);	
				}
		}
		// this is an exception to the rule, there is no "non-null" state to return from this method
		return true;
	}
	protected boolean validateList(ListStruct dataOperationResult mr) {
		if (this. == null
			mr.errorTr(416, data);   
		else
			for (Struct obj : data.getItems())
				this..validate(objmr);		
		if ((this. > 0) && (data.getSize() < this.))
			mr.errorTr(417, data);   
		if ((this. > 0) && (data.getSize() > this.))
			mr.errorTr(418, data);   
		return true;		
	}
	protected boolean validateScalar(Struct dataOperationResult mr) {
		if (this. == null) {
			mr.errorTr(420, data);   
			return false;
		}
		// if we are expecting a special class, try to resolve validation via that class 
		if (this..hasAttribute("Class") && (data != null)) {
			String cname = this..getAttribute("Class");
			if (data.getClass().getName().equals(cname) && (data instanceof ScalarStruct)) 
				return this..validate(((ScalarStruct)data).toInternalValue(this..), mr);
		}
		return this..validate(datamr);
	}
	public Struct wrap(Object dataOperationResult mr) {
		if (data == null
			return null;
		this.compile(mr);
		if (this. == .) {
			if (data instanceof RecordStruct) {
				Struct s = (Struct)data;
				// TODO check that type/inheritance is ok
				if (!s.hasExplicitType())
					s.setType(this);
				return s;
			}
			mr.errorTr(421, data);		
			return null;
		}
		if (this. == .) {
			if (data instanceof ListStruct) {
				Struct s = (Struct)data;
				// TODO check that type/inheritance is ok
				if (!s.hasExplicitType())
					s.setType(this);
				return s;
			}
			mr.errorTr(439, data);		
			return null;
		Struct s = this..wrap(datamr);
		if (s != null) {
			if (!s.hasExplicitType()  && (!"Any".equals(this.)))
				s.setType(this);
			return s;
		}
		return null;
	}
	public Struct wrapItem(Object dataOperationResult mr) {
		if (data == null
			return null;
		this.compile(mr);
		if (this. == .) {
			mr.errorTr(422, data);		
			return null;
		}
		if (this. == .
			return this..wrap(datamr);
		Struct s = this..wrap(datamr);
		if (s != null) {
			if (!s.hasExplicitType())
				s.setType(this);
			return s;
		}
		return null;
	}
	public Struct create(OperationResult mr) {
		this.compile(mr);
		Struct st = null;
		if (this. == .) {
			st = new RecordStruct();
		}		
		if (this. == .) {
			st = new ListStruct();
		}
		else {
			if (this..hasAttribute("Class")) {
				try {
					Class<?> spectype = this.getClass().getClassLoader().loadClass(this..getAttribute("Class"));
					st = (Structspectype.newInstance();
				catch (Exception x) {
					// TODO log
					return null;
				}
			}	
			else if (this. != null)
				st = this..create(mr);
		}
		// TODO err message if null
		if (st != null)
			st.setType(this);
		return st
	}
		if (this. != null
			return this..getPrimaryType();
		return null;
	}
	public CoreType getCoreType() {
		return this.;
	}
New to GrepCode? Check out our FAQ X