001 package de.deepamehta.core.model; 002 003 import org.codehaus.jettison.json.JSONObject; 004 005 import java.util.ArrayList; 006 import java.util.Collection; 007 import java.util.List; 008 import java.util.Map; 009 import java.util.logging.Logger; 010 011 012 013 /** 014 * Definition of an association between 2 topic types -- part of DeepaMehta's type system, 015 * like an association in a class diagram. Used to represent both, aggregations and compositions. 016 * ### FIXDOC: also assoc types have assoc defs 017 * 018 * @author <a href="mailto:jri@deepamehta.de">Jörg Richter</a> 019 */ 020 public class AssociationDefinitionModel extends AssociationModel { 021 022 // ---------------------------------------------------------------------------------------------- Instance Variables 023 024 private String instanceLevelAssocTypeUri; // derived, not serialized 025 026 private String parentTypeUri; // derived, not serialized 027 private String childTypeUri; // derived, not serialized 028 029 private String parentCardinalityUri; 030 private String childCardinalityUri; 031 032 private ViewConfigurationModel viewConfigModel; // is never null 033 034 private Logger logger = Logger.getLogger(getClass().getName()); 035 036 // ---------------------------------------------------------------------------------------------------- Constructors 037 038 public AssociationDefinitionModel(String typeUri, String parentTypeUri, String childTypeUri, 039 String parentCardinalityUri, String childCardinalityUri) { 040 this(-1, null, typeUri, parentTypeUri, childTypeUri, parentCardinalityUri, childCardinalityUri, null); 041 } 042 043 public AssociationDefinitionModel(long id, String uri, String typeUri, String parentTypeUri, String childTypeUri, 044 String parentCardinalityUri, String childCardinalityUri, 045 ViewConfigurationModel viewConfigModel) { 046 super(id, uri, typeUri, parentRoleModel(parentTypeUri), childRoleModel(childTypeUri)); 047 // 048 this.instanceLevelAssocTypeUri = instanceLevelAssocTypeUri(typeUri); 049 // 050 this.parentTypeUri = parentTypeUri; 051 this.childTypeUri = childTypeUri; 052 // 053 this.parentCardinalityUri = parentCardinalityUri; 054 this.childCardinalityUri = childCardinalityUri; 055 // 056 this.viewConfigModel = viewConfigModel != null ? viewConfigModel : new ViewConfigurationModel(); 057 } 058 059 // -------------------------------------------------------------------------------------------------- Public Methods 060 061 public String getInstanceLevelAssocTypeUri() { 062 return instanceLevelAssocTypeUri; 063 } 064 065 public String getParentTypeUri() { 066 return parentTypeUri; 067 } 068 069 public String getChildTypeUri() { 070 return childTypeUri; 071 } 072 073 public String getParentCardinalityUri() { 074 return parentCardinalityUri; 075 } 076 077 public String getChildCardinalityUri() { 078 return childCardinalityUri; 079 } 080 081 public ViewConfigurationModel getViewConfigModel() { 082 return viewConfigModel; 083 } 084 085 // --- 086 087 @Override 088 public void setTypeUri(String typeUri) { 089 super.setTypeUri(typeUri); 090 this.instanceLevelAssocTypeUri = instanceLevelAssocTypeUri(typeUri); 091 } 092 093 public void setParentCardinalityUri(String parentCardinalityUri) { 094 this.parentCardinalityUri = parentCardinalityUri; 095 } 096 097 public void setChildCardinalityUri(String childCardinalityUri) { 098 this.childCardinalityUri = childCardinalityUri; 099 } 100 101 public void setViewConfigModel(ViewConfigurationModel viewConfigModel) { 102 this.viewConfigModel = viewConfigModel; 103 } 104 105 // --- 106 107 public JSONObject toJSON() { 108 try { 109 JSONObject o = super.toJSON(); 110 o.put("parent_cardinality_uri", parentCardinalityUri); 111 o.put("child_cardinality_uri", childCardinalityUri); 112 viewConfigModel.toJSON(o); 113 return o; 114 } catch (Exception e) { 115 throw new RuntimeException("Serialization failed (" + this + ")", e); 116 } 117 } 118 119 // --- 120 121 @Override 122 public String toString() { 123 return "\n association definition (" + super.toString() + 124 ",\n parent cardinality=\"" + parentCardinalityUri + 125 "\",\n child cardinality=\"" + childCardinalityUri + 126 "\",\n " + viewConfigModel + ")\n"; 127 } 128 129 // ----------------------------------------------------------------------------------------- Package Private Methods 130 131 static AssociationDefinitionModel fromJSON(JSONObject assocDef, String parentTypeUri) { 132 try { 133 long id = assocDef.optLong("id", -1); 134 String uri = null; 135 String typeUri = assocDef.getString("assoc_type_uri"); 136 String childTypeUri = assocDef.getString("child_type_uri"); 137 // 138 if (!assocDef.has("parent_cardinality_uri") && !typeUri.equals("dm4.core.composition_def")) { 139 throw new RuntimeException("\"parent_cardinality_uri\" is missing"); 140 } 141 String parentCardinalityUri = assocDef.optString("parent_cardinality_uri", "dm4.core.one"); 142 String childCardinalityUri = assocDef.getString("child_cardinality_uri"); 143 // 144 ViewConfigurationModel viewConfigModel = new ViewConfigurationModel(assocDef); 145 // 146 return new AssociationDefinitionModel(id, uri, typeUri, parentTypeUri, childTypeUri, 147 parentCardinalityUri, childCardinalityUri, viewConfigModel); 148 } catch (Exception e) { 149 throw new RuntimeException("Parsing AssociationDefinitionModel failed (JSONObject=" + assocDef + ")", e); 150 } 151 } 152 153 static void toJSON(Collection<AssociationDefinitionModel> assocDefs, JSONObject o) throws Exception { 154 List assocDefList = new ArrayList(); 155 for (AssociationDefinitionModel assocDef : assocDefs) { 156 assocDefList.add(assocDef.toJSON()); 157 } 158 o.put("assoc_defs", assocDefList); 159 } 160 161 // ------------------------------------------------------------------------------------------------- Private Methods 162 163 private static TopicRoleModel parentRoleModel(String parentTypeUri) { 164 return new TopicRoleModel(parentTypeUri, "dm4.core.parent_type"); 165 } 166 167 private static TopicRoleModel childRoleModel(String childTypeUri) { 168 return new TopicRoleModel(childTypeUri, "dm4.core.child_type"); 169 } 170 171 // --- 172 173 private String instanceLevelAssocTypeUri(String typeUri) { 174 if (typeUri.equals("dm4.core.aggregation_def")) { 175 return "dm4.core.aggregation"; 176 } else if (typeUri.equals("dm4.core.composition_def")) { 177 return "dm4.core.composition"; 178 } else { 179 throw new RuntimeException("Unexpected association type URI: \"" + typeUri + "\""); 180 } 181 } 182 }