org.openrdf.repository.object.advisers.FieldBehaviour Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alibaba-repository-object Show documentation
Show all versions of alibaba-repository-object Show documentation
The Object Repository maps Java objects to and from RDF resources and OWL classes to Java classes in a non-intrusive manner that enables developers to work at the object level.
The newest version!
/*
* Copyright (c) 2012 3 Round Stones Inc., Some rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the openrdf.org nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
package org.openrdf.repository.object.advisers;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Set;
import org.openrdf.query.BindingSet;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.object.advice.Advice;
import org.openrdf.repository.object.advisers.helpers.PropertySet;
import org.openrdf.repository.object.traits.Mergeable;
import org.openrdf.repository.object.traits.ObjectMessage;
import org.openrdf.repository.object.traits.PropertyConsumer;
import org.openrdf.repository.object.traits.Refreshable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Reads and write properties to/from an RDF store before and after a method is
* called that uses fields with an @Iri annotation.
*/
public final class FieldBehaviour implements Advice, Mergeable,
Refreshable, PropertyConsumer {
private final Logger logger = LoggerFactory.getLogger(FieldBehaviour.class);
private final Class> concept;
private final Class> type;
private final Field field;
private final PropertySet property;
private final Object proxy;
private volatile boolean populated;
public FieldBehaviour(PropertySet property, Field field, Object proxy) {
assert field != null;
assert property != null;
assert proxy != null;
this.concept = field.getDeclaringClass();
this.type = field.getType();
this.field = field;
this.property = property;
this.proxy = proxy;
try {
field.setAccessible(true);
} catch (SecurityException e) {
logger.warn(e.toString(), e);
}
}
@Override
public String toString() {
return field.toString();
}
public void usePropertyBindings(String binding, List results) {
if (property instanceof PropertyConsumer) {
String var = binding + "_" + field.getName();
if (results.get(0).getBindingNames().contains(var)) {
PropertyConsumer pc = (PropertyConsumer) property;
pc.usePropertyBindings(var, results);
}
}
}
public void refresh() {
property.refresh();
}
public void merge(Object source) throws RepositoryException {
if (concept.isAssignableFrom(source.getClass())) {
try {
Object value = field.get(source);
if (value != null) {
if (Set.class.equals(this.type)) {
property.addAll((Set>) value);
} else {
property.add(value);
}
}
} catch (IllegalArgumentException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
IllegalAccessError error;
error = new IllegalAccessError(e.getMessage());
error.initCause(e);
throw error;
}
}
}
public Object intercept(ObjectMessage message) throws Exception {
if (populated)
return message.proceed();
Object fieldValue = getFieldValue();
try {
populateFields(fieldValue);
} catch (IllegalAccessException e) {
throw error(e);
}
try {
populated = true;
return message.proceed();
} finally {
populated = false;
try {
storeFields(fieldValue);
} catch (IllegalAccessException e) {
throw error(e);
}
}
}
private IllegalAccessError error(IllegalAccessException e) {
IllegalAccessError error = new IllegalAccessError(e.getMessage());
error.initCause(e);
return error;
}
private void populateFields(Object fieldValue)
throws IllegalAccessException {
if (concept.isAssignableFrom(proxy.getClass())) {
if (fieldValue != null && String.class.equals(type)) {
field.set(proxy, fieldValue.toString());
} else {
field.set(proxy, fieldValue);
}
}
for (Field f : proxy.getClass().getDeclaredFields()) {
if (concept.isAssignableFrom(f.getType())) {
Object behaviour = f.get(proxy);
if (behaviour != null) {
if (fieldValue != null && String.class.equals(type)) {
field.set(behaviour, fieldValue.toString());
} else {
field.set(behaviour, fieldValue);
}
}
}
}
}
private void storeFields(Object populated) throws IllegalAccessException {
if (concept.isAssignableFrom(proxy.getClass())) {
Object get = field.get(proxy);
if (get != populated) {
setFieldValue(get);
}
}
for (Field f : proxy.getClass().getDeclaredFields()) {
if (concept.isAssignableFrom(f.getType())) {
Object behaviour = f.get(proxy);
if (behaviour != null) {
Object get = field.get(behaviour);
if (get != populated) {
setFieldValue(get);
}
}
}
}
}
private Object getFieldValue() {
if (Set.class.equals(type))
return property.getAll();
Object single = property.getSingle();
if (single == null)
return nil(type);
return single;
}
private void setFieldValue(Object get) {
if (Set.class.equals(type))
property.setAll((Set>) get);
property.setSingle(get);
}
private Object nil(Class> type) {
if (!type.isPrimitive())
return null;
if (Void.TYPE.equals(type))
return null;
if (Boolean.TYPE.equals(type))
return Boolean.FALSE;
if (Character.TYPE.equals(type))
return Character.valueOf((char) 0);
if (Byte.TYPE.equals(type))
return Byte.valueOf((byte) 0);
if (Short.TYPE.equals(type))
return Short.valueOf((short) 0);
if (Integer.TYPE.equals(type))
return Integer.valueOf((int) 0);
if (Long.TYPE.equals(type))
return Long.valueOf((long) 0);
if (Float.TYPE.equals(type))
return Float.valueOf((float) 0);
if (Double.TYPE.equals(type))
return Double.valueOf((double) 0);
throw new AssertionError();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy