00001 package edu.tum.cs.srldb.datadict; 00002 00003 import java.util.Map.Entry; 00004 00005 import edu.tum.cs.srldb.Database; 00006 import edu.tum.cs.srldb.IRelationArgument; 00007 import edu.tum.cs.srldb.Item; 00008 import edu.tum.cs.srldb.Link; 00009 import edu.tum.cs.srldb.Object; 00010 import edu.tum.cs.srldb.datadict.domain.AutomaticDomain; 00011 import edu.tum.cs.srldb.datadict.domain.Domain; 00012 00013 public class AutomaticDataDictionary extends DataDictionary { 00014 00015 private static final long serialVersionUID = 1L; 00016 00017 public AutomaticDataDictionary() { 00018 super(); 00019 } 00020 00021 @Override 00022 public void onCommitObject(Object o) throws DDException { 00023 // add the object type to the data dictionary if it isn't contained yet 00024 DDObject ddo = this.getObject(o.objType()); 00025 if(ddo == null) 00026 addObject(ddo = new DDObject(o.objType())); 00027 // process the attributes 00028 onCommitItemAttributes(o, ddo); 00029 } 00030 00031 protected void onCommitItemAttributes(Item item, DDItem ddi) throws DDException { 00032 // add all attributes that aren't contained yet as attributes with automatic domains 00033 // and extend all automatic attribute domains 00034 for(Entry<String,String> e : item.getAttributes().entrySet()) { 00035 String attrName = e.getKey(); 00036 DDAttribute dda = this.getAttribute(attrName); 00037 if(dda == null) { 00038 AutomaticDomain dom = new AutomaticDomain("dom" + Database.upperCaseString(attrName)); 00039 addAttribute(dda = new DDAttribute(attrName, dom)); 00040 ddi.addAttribute(dda); 00041 dom.addValue(e.getValue()); 00042 } 00043 else { 00044 Domain<?> dom = dda.getDomain(); 00045 if(dom instanceof AutomaticDomain) 00046 ((AutomaticDomain)dom).addValue(e.getValue()); 00047 } 00048 } 00049 } 00050 00051 @Override 00052 public void onCommitLink(Link link) throws DDException { 00053 DDRelation ddlink = getRelation(link.getName()); 00054 if(ddlink == null) { // this relation is not yet in the data dictionary 00055 // get a data dictionary definition for each argument 00056 IRelationArgument[] args = link.getArguments(); 00057 IDDRelationArgument[] ddArgs = new IDDRelationArgument[args.length]; 00058 int i = 0; 00059 for(IRelationArgument arg : args) { 00060 // if it's an object, check if we have a definition for that type of object 00061 if(arg instanceof Object) { 00062 Object obj = (Object) arg; 00063 ddArgs[i] = getObject(obj.objType()); 00064 } 00065 // it's a constant (which is treated as an attribute value) 00066 else { 00067 // add an attribute with an AutomaticDomain if necessary 00068 String domName = "dom" + Database.upperCaseString(link.getName()) + i; 00069 DDAttribute ddattr = this.attributes.get(domName); 00070 if(ddattr == null) { 00071 DDConstantArgument ddconst = new DDConstantArgument(link.getName() + i, new AutomaticDomain(domName)); 00072 ddArgs[i] = ddconst; 00073 addAttribute(ddconst); 00074 } 00075 } 00076 i++; 00077 } 00078 // create the relation definition and add it to the dictionary 00079 ddlink = new DDRelation(link.getName(), ddArgs); 00080 this.addRelation(ddlink); 00081 } 00082 // check the link's attributes (and extend their domains if necessary) 00083 onCommitItemAttributes(link, ddlink); 00084 // check for constant arguments (and extend the corresponding domains if necessary) 00085 int i = 0; 00086 for(IDDRelationArgument argtype : ddlink.getArguments()) { 00087 if(argtype instanceof DDConstantArgument) { 00088 Domain dom = getDomain(argtype.getDomainName()); 00089 // extend the domain if applicable 00090 IRelationArgument arg = link.getArguments()[i]; 00091 String value = arg.getConstantName(); 00092 if(!dom.containsString(value)) { 00093 if(dom instanceof AutomaticDomain) { 00094 ((AutomaticDomain)dom).addValue(value); 00095 } 00096 else 00097 throw new DDException("Argument " + (i+1) + " of " + link.toString() + " is invalid; not in domain " + dom.getName()); 00098 } 00099 } 00100 i++; 00101 } 00102 } 00103 }