001 package de.deepamehta.core.model; 002 003 import de.deepamehta.core.Identifiable; 004 import de.deepamehta.core.JSONEnabled; 005 006 import org.codehaus.jettison.json.JSONObject; 007 008 009 010 public abstract class DeepaMehtaObjectModel implements Identifiable, JSONEnabled, Cloneable { 011 012 // ---------------------------------------------------------------------------------------------- Instance Variables 013 014 // ### TODO: make these private? 015 protected long id; // is -1 in models used for a create operation. ### FIXDOC 016 // is never -1 in models used for an update operation. 017 protected String uri; // is never null in models used for a create operation, may be empty. ### FIXDOC 018 // may be null in models used for an update operation. 019 protected String typeUri; // is never null in models used for a create operation. ### FIXDOC 020 // may be null in models used for an update operation. 021 protected SimpleValue value; // is never null in models used for a create operation, may be constructed 022 // on empty string. ### FIXDOC 023 // may be null in models used for an update operation. 024 protected CompositeValueModel composite; // is never null, may be empty. ### FIXDOC 025 026 // ---------------------------------------------------------------------------------------------------- Constructors 027 028 public DeepaMehtaObjectModel(String typeUri) { 029 this(-1, typeUri); 030 } 031 032 public DeepaMehtaObjectModel(String typeUri, SimpleValue value) { 033 this(null, typeUri, value); 034 } 035 036 public DeepaMehtaObjectModel(String typeUri, CompositeValueModel composite) { 037 this(null, typeUri, composite); 038 } 039 040 public DeepaMehtaObjectModel(String uri, String typeUri) { 041 this(-1, uri, typeUri, null, null); 042 } 043 044 public DeepaMehtaObjectModel(String uri, String typeUri, SimpleValue value) { 045 this(-1, uri, typeUri, value, null); 046 } 047 048 public DeepaMehtaObjectModel(String uri, String typeUri, CompositeValueModel composite) { 049 this(-1, uri, typeUri, null, composite); 050 } 051 052 public DeepaMehtaObjectModel(long id) { 053 this(id, null, null); 054 } 055 056 public DeepaMehtaObjectModel(long id, CompositeValueModel composite) { 057 this(id, null, composite); 058 } 059 060 public DeepaMehtaObjectModel(long id, String typeUri) { 061 this(id, typeUri, null); 062 } 063 064 public DeepaMehtaObjectModel(long id, String typeUri, CompositeValueModel composite) { 065 this(id, null, typeUri, null, composite); 066 } 067 068 /** 069 * @param id Optional (-1 is a valid value and represents "not set"). 070 * @param uri Optional (<code>null</code> is a valid value). 071 * @param typeUri Mandatory in the context of a create operation. 072 * Optional (<code>null</code> is a valid value) in the context of an update opereation. 073 * @param value Optional (<code>null</code> is a valid value). 074 * @param composite Optional (<code>null</code> is a valid value and is transformed into an empty composite). 075 */ 076 public DeepaMehtaObjectModel(long id, String uri, String typeUri, SimpleValue value, 077 CompositeValueModel composite) { 078 this.id = id; 079 this.uri = uri; 080 this.typeUri = typeUri; 081 this.value = value; 082 this.composite = composite != null ? composite : new CompositeValueModel(); 083 } 084 085 public DeepaMehtaObjectModel(DeepaMehtaObjectModel model) { 086 this(model.id, model.uri, model.typeUri, model.value, model.composite); 087 } 088 089 /** 090 * Used for regular objects: topics and associations. 091 */ 092 public DeepaMehtaObjectModel(JSONObject model) { 093 try { 094 this.id = model.optLong("id", -1); 095 this.uri = model.optString("uri", null); 096 this.typeUri = model.optString("type_uri", null); 097 this.value = model.has("value") ? new SimpleValue(model.get("value")) : null; 098 this.composite = model.has("composite") ? new CompositeValueModel(model.getJSONObject("composite")) 099 : new CompositeValueModel(); 100 } catch (Exception e) { 101 throw new RuntimeException("Parsing DeepaMehtaObjectModel failed (JSONObject=" + model + ")", e); 102 } 103 } 104 105 /** 106 * Used for types: topic types and association types. 107 */ 108 public DeepaMehtaObjectModel(JSONObject typeModel, String typeUri) { 109 try { 110 this.id = typeModel.optLong("id", -1); 111 this.uri = typeModel.optString("uri"); 112 this.typeUri = typeUri; 113 this.value = new SimpleValue(typeModel.get("value")); 114 this.composite = new CompositeValueModel(); 115 } catch (Exception e) { 116 throw new RuntimeException("Parsing DeepaMehtaObjectModel failed (JSONObject=" + typeModel + 117 ", typeUri=\"" + typeUri + "\")", e); 118 } 119 } 120 121 // -------------------------------------------------------------------------------------------------- Public Methods 122 123 // --- ID --- 124 125 public long getId() { 126 return id; 127 } 128 129 public void setId(long id) { 130 this.id = id; 131 } 132 133 // --- URI --- 134 135 public String getUri() { 136 return uri; 137 } 138 139 public void setUri(String uri) { 140 this.uri = uri; 141 } 142 143 // --- Type URI --- 144 145 public String getTypeUri() { 146 return typeUri; 147 } 148 149 public void setTypeUri(String typeUri) { 150 this.typeUri = typeUri; 151 } 152 153 // --- Simple Value --- 154 155 public SimpleValue getSimpleValue() { 156 return value; 157 } 158 159 // --- 160 161 public void setSimpleValue(String value) { 162 setSimpleValue(new SimpleValue(value)); 163 } 164 165 public void setSimpleValue(int value) { 166 setSimpleValue(new SimpleValue(value)); 167 } 168 169 public void setSimpleValue(long value) { 170 setSimpleValue(new SimpleValue(value)); 171 } 172 173 public void setSimpleValue(boolean value) { 174 setSimpleValue(new SimpleValue(value)); 175 } 176 177 public void setSimpleValue(SimpleValue value) { 178 this.value = value; 179 } 180 181 // --- Composite Value --- 182 183 public CompositeValueModel getCompositeValueModel() { 184 return composite; 185 } 186 187 public void setCompositeValue(CompositeValueModel comp) { 188 this.composite = comp; 189 } 190 191 // --- 192 193 public void set(DeepaMehtaObjectModel model) { 194 setId(model.getId()); 195 setUri(model.getUri()); 196 setTypeUri(model.getTypeUri()); 197 setSimpleValue(model.getSimpleValue()); 198 setCompositeValue(model.getCompositeValueModel()); 199 } 200 201 // --- 202 203 public abstract RoleModel createRoleModel(String roleTypeUri); 204 205 206 207 // === Serialization === 208 209 @Override 210 public JSONObject toJSON() { 211 try { 212 // Note: for models used for topic/association enrichment (e.g. timestamps, permissions) 213 // default values must be set in case they are not fully initialized. 214 setDefaults(); 215 // 216 JSONObject o = new JSONObject(); 217 o.put("id", id); 218 o.put("uri", uri); 219 o.put("type_uri", typeUri); 220 o.put("value", value.value()); 221 o.put("composite", composite.toJSON()); 222 return o; 223 } catch (Exception e) { 224 throw new RuntimeException("Serialization failed (" + this + ")", e); 225 } 226 } 227 228 229 230 // === Java API === 231 232 @Override 233 public DeepaMehtaObjectModel clone() { 234 try { 235 DeepaMehtaObjectModel model = (DeepaMehtaObjectModel) super.clone(); 236 model.composite = composite.clone(); 237 return model; 238 } catch (Exception e) { 239 throw new RuntimeException("Cloning a DeepaMehtaObjectModel failed", e); 240 } 241 } 242 243 @Override 244 public boolean equals(Object o) { 245 return ((DeepaMehtaObjectModel) o).id == id; 246 } 247 248 @Override 249 public int hashCode() { 250 return ((Long) id).hashCode(); 251 } 252 253 @Override 254 public String toString() { 255 return "id=" + id + ", uri=\"" + uri + "\", typeUri=\"" + typeUri + "\", value=\"" + value + 256 "\", composite=" + composite; 257 } 258 259 260 261 // ------------------------------------------------------------------------------------------------- Private Methods 262 263 // ### TODO: a principal copy exists in Neo4jStorage. 264 // Should this be public? It is not meant to be called by the user. 265 private void setDefaults() { 266 if (getUri() == null) { 267 setUri(""); 268 } 269 if (getSimpleValue() == null) { 270 setSimpleValue(""); 271 } 272 } 273 }