/* ************************************************************************
#
# 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.HashMap;
import divconq.bus.Message;
import divconq.util.ArrayUtil;
import divconq.util.StringUtil;
import divconq.xml.XElement;
public class ServiceSchema {
protected SchemaManager man = null;
protected HashMap<String, Service> services = new HashMap<String, Service>();
public ServiceSchema(SchemaManager man) {
this.man = man;
}
public void load(Schema schema, XElement db) {
for (XElement serel : db.selectAll("Service")) {
String sname = serel.getAttribute("Name");
//String sclass = serel.getAttribute("Class");
if (StringUtil.isEmpty(sname))
continue;
Service ser = this.services.get(sname);
if (ser == null) {
ser = new Service();
ser.name = sname;
this.services.put(sname, ser);
}
for (XElement secel : serel.selectAll("Secure")) {
String[] tags = secel.hasAttribute("Tags")
? secel.getAttribute("Tags").split(",")
: new String[] { "Guest", "User" };
for (XElement ftel : secel.selectAll("Feature")) {
String fname = ftel.getAttribute("Name");
if (StringUtil.isEmpty(fname))
continue;
Feature fet = ser.features.get(fname);
if (fet == null) {
fet = new Feature();
fet.name = fname;
ser.features.put(fname, fet);
}
for (XElement opel : ftel.selectAll("Op")) {
String oname = opel.getAttribute("Name");
if (StringUtil.isEmpty(oname))
continue;
Op opt = new Op();
opt.name = oname;
opt.securityTags = tags;
fet.ops.put(oname, opt);
XElement req = opel.find("Request", "RecRequest");
if (req != null)
opt.request = this.man.loadDataType(schema, req);
XElement resp = opel.find("Response", "RecResponse");
if (resp != null)
opt.response = this.man.loadDataType(schema, resp);
}
for (XElement opel : ftel.selectAll("OpMod")) {
String oname = opel.getAttribute("Name");
if (StringUtil.isEmpty(oname))
continue;
String[] curr = fet.opmods.get(oname);
if (curr != null)
curr = ArrayUtil.addAll(curr, tags);
else
curr = tags;
fet.opmods.put(oname, curr);
}
}
}
}
// TODO we need to have additional table info stored locally - but at moment at least we can validate against Services
}
public DataType getRequestType(Message msg) {
Op opt = this.getOp(msg.getFieldAsString("Service"), msg.getFieldAsString("Feature"), msg.getFieldAsString("Op"));
if (opt != null)
return opt.request;
return null;
}
public DataType getResponseType(String service, String feature, String op) {
Op opt = this.getOp(service, feature, op);
if (opt != null)
return opt.response;
return null;
}
public Op getOp(Message msg) {
return this.getOp(msg.getFieldAsString("Service"), msg.getFieldAsString("Feature"), msg.getFieldAsString("Op"));
}
public Op getOp(String service, String feature, String op) {
if (StringUtil.isEmpty(service))
return null;
Service s = this.services.get(service);
if (s == null)
return null;
if (StringUtil.isEmpty(feature))
feature = "default";
Feature f = s.features.get(feature);
if (f == null)
return null;
if (StringUtil.isEmpty(op))
op = "default";
return f.ops.get(op);
}
public String[] getOpSecurity(Message msg) {
return this.getOpSecurity(msg.getFieldAsString("Service"), msg.getFieldAsString("Feature"), msg.getFieldAsString("Op"));
}
public String[] getOpSecurity(String service, String feature, String op) {
if (StringUtil.isEmpty(service))
return null;
Service s = this.services.get(service);
if (s == null)
return null;
if (StringUtil.isEmpty(feature))
feature = "default";
Feature f = s.features.get(feature);
if (f == null)
return null;
if (StringUtil.isEmpty(op))
op = "default";
return f.opmods.get(op);
}
public class Service {
protected String name = null;
protected HashMap<String, Feature> features = new HashMap<String, Feature>();
}
public class Feature {
protected String name = null;
protected HashMap<String, Op> ops = new HashMap<String, Op>();
protected HashMap<String, String[]> opmods = new HashMap<String, String[]>();
}
public class Op {
protected String name = null;
protected String[] securityTags = null;
protected DataType request = null;
protected DataType response = null;
public boolean isTagged(String... tags) {
if (this.securityTags == null)
return false;
for (int i = 0; i < this.securityTags.length; i++) {
String has = this.securityTags[i];
for (String wants : tags) {
if (has.equals(wants))
return true;
}
}
return false;
}
}
public void compile() {
for (Service s : this.services.values()) {
for (Feature f : s.features.values()) {
for (Op o : f.ops.values()) {
if (o.request != null)
o.request.compile();
if (o.response != null)
o.response.compile();
}
}
}
}
public void remove(String name) {
this.services.remove(name);
}
}