All Downloads are FREE. Search and download functionalities are using the official Maven repository.

iot.jcypher.domain.genericmodel.DomainObject Maven / Gradle / Ivy

Go to download

Provides seamlessly integrated Java access to graph databases (Neo4J) at different levels of abstraction.

The newest version!
/************************************************************************
 * Copyright (c) 2015 IoT-Solutions e.U.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ************************************************************************/

package iot.jcypher.domain.genericmodel;

import iot.jcypher.domain.genericmodel.internal.InternalAccess;
import iot.jcypher.domain.internal.DomainAccess;
import iot.jcypher.domain.internal.IIntDomainAccess;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;


public class DomainObject {

	private DOType domainObjectType;
	private Object rawObject;

	public DomainObject(DOType doType) {
		this(doType, true);
	}
	
	DomainObject(DOType doType, boolean toNursery) {
		super();
		if (doType == null)
			throw new RuntimeException("a domain object must be constructed with a domain object type");
		this.domainObjectType = doType;
		if (toNursery)
			this.domainObjectType.getDomainModel().addNurseryObject(getRawObject(), this);
	}

	/**
	 * Answer the type of this generic domain object
	 * @return a DOType
	 */
	public DOType getDomainObjectType() {
		return domainObjectType;
	}
	
	/**
	 * Set a field (attribute) value
	 * @param fieldName
	 * @param value
	 */
	public void setFieldValue(String fieldName, Object value) {
		DOField field = this.domainObjectType.getFieldByName(fieldName);
		if (field == null)
			throw new RuntimeException("field: " + fieldName + " not found in: " + this.domainObjectType.getName());
		if (field.getComponentTypeName() != null)
			throw new RuntimeException("field: " + fieldName + " is a list field, use list field accessors instead ");
		Object val = value;
		if (value instanceof DomainObject)
			val = ((DomainObject)value).getRawObject();
		field.setValue(this.getRawObject(), val);
	}
	
	/**
	 * Add a value to a list or array field
	 * @param fieldName
	 * @param value
	 */
	public void addListFieldValue(String fieldName, Object value) {
		Object val = value;
		if (value instanceof DomainObject)
			val = ((DomainObject)value).getRawObject();
		Object lst = getFieldValue(fieldName, true); // internal
		
		DOField fld = getDomainObjectType().getFieldByName(fieldName);
		String ctn = fld.getComponentTypeName();
		Class clazz;
		try {
			clazz = getDomainObjectType().getDomainModel().getClassForName(ctn);
			if (!clazz.isAssignableFrom(val.getClass()))
				throw new RuntimeException("value must be of type or subtype of: [" + clazz.getName() + "]");
			lst = tryInitListOrArray(lst, fld, clazz);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
		
		if (lst instanceof List) {
			@SuppressWarnings("unchecked")
			List list = (List)lst;
			list.add(val);
		} else if (lst != null && lst.getClass().isArray()) {
			int len = Array.getLength(lst);
			Object array = Array.newInstance(clazz, len + 1);
			for (int i = 0; i < len; i++) {
				Array.set(array, i, Array.get(lst, i));
			}
			Array.set(array, len, val);
		} else {
			if (!getDomainObjectType().getFieldByName(fieldName).isListOrArray())
				throw new RuntimeException("field: [" + fieldName + "] is neither list nor array");
			if (lst == null)
				throw new RuntimeException("field: [" + fieldName + "] has not been initialized as list or array");
		}
	}
	
	/**
	 * Add a value to a list or array field at the given index.
	 * 
Shifts the element currently at that position * (if any) and any subsequent elements to the right (adds one to their * indices). * @param fieldName * @param index * @param value */ public void insertListFieldValue(String fieldName, int index, Object value) { Object val = value; if (value instanceof DomainObject) val = ((DomainObject)value).getRawObject(); Object lst = getFieldValue(fieldName, true); // internal DOField fld = getDomainObjectType().getFieldByName(fieldName); String ctn = fld.getComponentTypeName(); Class clazz; try { clazz = getDomainObjectType().getDomainModel().getClassForName(ctn); if (!clazz.isAssignableFrom(val.getClass())) throw new RuntimeException("value must be of type or subtype of: [" + clazz.getName() + "]"); lst = tryInitListOrArray(lst, fld, clazz); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } if (lst instanceof List) { @SuppressWarnings("unchecked") List list = (List)lst; list.add(index, val); } else if (lst != null && lst.getClass().isArray()) { int len = Array.getLength(lst); Object array = Array.newInstance(clazz, len + 1); for (int i = 0; i < index; i++) { Array.set(array, i, Array.get(lst, i)); } Array.set(array, index, val); for (int i = index + 1; i < len + 1; i++) { Array.set(array, i, Array.get(lst, i - 1)); } } else { if (!getDomainObjectType().getFieldByName(fieldName).isListOrArray()) throw new RuntimeException("field: [" + fieldName + "] is neither list nor array"); if (lst == null) throw new RuntimeException("field: [" + fieldName + "] has not been initialized as list or array"); } } /** * Get a field (attribute) value * @param fieldName * @return */ public Object getFieldValue(String fieldName) { return getFieldValue(fieldName, false); // not internal } Object getFieldValue(String fieldName, boolean internal) { DOField field = this.domainObjectType.getFieldByName(fieldName); if (field == null) throw new RuntimeException("field: " + fieldName + " not found in: " + this.domainObjectType.getName()); if (!internal && field.getComponentTypeName() != null) throw new RuntimeException("field: " + fieldName + " is a list field, use list field accessors instead "); Object raw = field.getValue(this.getRawObject()); DomainObject gdo = getForRawObject(raw); if (gdo != null) return gdo; return raw; } /** * if the field is a list or array, answer the value at the given index. * @param fieldName * @param index * @return */ public Object getListFieldValue(String fieldName, int index) { Object ret = null; Object val = getFieldValue(fieldName, true); // internal if (val instanceof List) { List list = (List)val; Object cval = list.get(index); DomainObject gdo = getForRawObject(cval); if (gdo != null) ret = gdo; else ret = cval; } else if (val != null && val.getClass().isArray()) { Object aval = Array.get(val, index); DomainObject gdo = getForRawObject(aval); if (gdo != null) ret = gdo; else ret = aval; } else { if (!getDomainObjectType().getFieldByName(fieldName).isListOrArray()) throw new RuntimeException("field: [" + fieldName + "] is neither list nor array"); if (val == null) throw new RuntimeException("list or array field: [" + fieldName + "] is null"); } return ret; } /** * Returns the index of the first occurrence of the specified value * in the list field, or -1 if the list field does not contain the value. * @param fieldName * @param value * @return */ public int getIndexOfValue(String fieldName, Object value) { int ret = -1; Object val = value; if (value instanceof DomainObject) val = ((DomainObject)value).getRawObject(); Object lst = getFieldValue(fieldName, true); // internal if (lst instanceof List) { List list = (List)lst; for (int i = 0; i < list.size(); i++) { Object obj = list.get(i); if (obj.equals(val)) { ret = i; break; } } } else if (lst != null && lst.getClass().isArray()) { int len = Array.getLength(lst); for (int i = 0; i < len; i++) { Object obj = Array.get(lst, i); if (obj.equals(val)) { ret = i; break; } } } else { if (!getDomainObjectType().getFieldByName(fieldName).isListOrArray()) throw new RuntimeException("field: [" + fieldName + "] is neither list nor array"); if (lst == null) throw new RuntimeException("list or array field: [" + fieldName + "] is null"); } return ret; } /** * Removes all of the elements from the list field. * @param fieldName */ public void clearListField(String fieldName) { Object val = getFieldValue(fieldName, true); // internal if (val instanceof List) ((List)val).clear(); else if (val != null && val.getClass().isArray()) { DOField fld = getDomainObjectType().getFieldByName(fieldName); String ctn = fld.getComponentTypeName(); Class clazz; try { clazz = getDomainObjectType().getDomainModel().getClassForName(ctn); tryInitListOrArray(null, fld, clazz); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } else { if (!getDomainObjectType().getFieldByName(fieldName).isListOrArray()) throw new RuntimeException("field: [" + fieldName + "] is neither list nor array"); if (val == null) throw new RuntimeException("list or array field: [" + fieldName + "] is null"); } } /** * Remove a value from a list at the given index. *
Shifts any subsequent elements to the left (subtracts one from their indices). * @param fieldName * @param index */ public void removeListFieldValue(String fieldName, int index) { Object val = getFieldValue(fieldName, true); // internal DOField fld = getDomainObjectType().getFieldByName(fieldName); String ctn = fld.getComponentTypeName(); Class clazz; try { clazz = getDomainObjectType().getDomainModel().getClassForName(ctn); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } if (val instanceof List) ((List)val).remove(index); else if (val != null && val.getClass().isArray()) { int len = Array.getLength(val); Object array = Array.newInstance(clazz, len - 1); for (int i = 0; i < index; i++) { Array.set(array, i, Array.get(val, i)); } for (int i = index; i < len - 1; i++) { Array.set(array, i, Array.get(val, i - 1)); } } else { if (!getDomainObjectType().getFieldByName(fieldName).isListOrArray()) throw new RuntimeException("field: [" + fieldName + "] is neither list nor array"); if (val == null) throw new RuntimeException("list or array field: [" + fieldName + "] is null"); } } /** * Answer the length of a list field * @param fieldName * @return */ public int getListFieldLength(String fieldName) { int ret = -1; Object val = getFieldValue(fieldName, true); // internal if (val instanceof List) ret = ((List)val).size(); else if (val != null && val.getClass().isArray()) { ret = Array.getLength(val); } else { if (!getDomainObjectType().getFieldByName(fieldName).isListOrArray()) throw new RuntimeException("field: [" + fieldName + "] is neither list nor array"); if (val == null) throw new RuntimeException("list or array field: [" + fieldName + "] is null"); } return ret; } private Object tryInitListOrArray(Object list, DOField fld, Class componentType) throws ClassNotFoundException { Object ret = list; if (list == null) { // try to initialize list or array field with empty list / array if (fld.isBuidInType()) { Class lstClazz = getDomainObjectType().getDomainModel().getClassForName(fld.getTypeName()); if (List.class.isAssignableFrom(lstClazz)) ret = new ArrayList(); else if (lstClazz.isArray()) ret = Array.newInstance(componentType, 0); if (ret != null) fld.setValue(this.getRawObject(), ret); } } return ret; } private DomainObject getForRawObject(Object raw) { DomainObject gdo = null; if (raw != null) { DomainAccess da = InternalAccess.getDomainAccess(this.domainObjectType.getDomainModel()); gdo = ((IIntDomainAccess)da).getInternalDomainAccess().getGenericDomainObject(raw); if (gdo == null) gdo = this.domainObjectType.getDomainModel().getNurseryObject(raw); } return gdo; } void setRawObject(Object rawObject) { this.rawObject = rawObject; } Object getRawObject() { if (this.rawObject == null) { try { this.rawObject = this.domainObjectType.getRawType().newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { throw new RuntimeException(e); } } return this.rawObject; } }