View Javadoc

1   /*
2    * Copyright (c) 2007, James Leigh All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions are met:
6    * 
7    * - Redistributions of source code must retain the above copyright notice, this
8    *   list of conditions and the following disclaimer.
9    * - Redistributions in binary form must reproduce the above copyright notice,
10   *   this list of conditions and the following disclaimer in the documentation
11   *   and/or other materials provided with the distribution. 
12   * - Neither the name of the openrdf.org nor the names of its contributors may
13   *   be used to endorse or promote products derived from this software without
14   *   specific prior written permission.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   * 
28   */
29  package org.openrdf.elmo.sesame;
30  
31  import java.beans.PropertyDescriptor;
32  import java.lang.reflect.Method;
33  
34  import org.openrdf.elmo.annotations.inverseOf;
35  import org.openrdf.elmo.annotations.rdf;
36  import org.openrdf.elmo.sesame.helpers.PropertyChanger;
37  import org.openrdf.model.Resource;
38  import org.openrdf.model.URI;
39  import org.openrdf.model.Value;
40  import org.openrdf.repository.RepositoryException;
41  import org.openrdf.repository.contextaware.ContextAwareConnection;
42  
43  /**
44   * Extends {@link SesamePropertyFactory} by creating
45   * {@link org.openrdf.elmo.ElmoProperty} that update the equivalent and
46   * inverseOf predicates.`
47   * 
48   * @author James Leigh
49   * 
50   * @param <E>
51   *            the property type
52   */
53  public class InferencingPropertyFactory<E> extends SesamePropertyFactory<E> {
54  
55  	private URI[] equivalent;
56  
57  	private URI[] inverseOf;
58  
59  	@Override
60  	public SesamePropertyFactory<E> setPropertyDescriptor(
61  			PropertyDescriptor property) {
62  		Method getter = property.getReadMethod();
63  		if (getter != null) {
64  			inverseOf ann = getter.getAnnotation(inverseOf.class);
65  			if (getter.isAnnotationPresent(rdf.class)) {
66  				String[] eq = getter.getAnnotation(rdf.class).value();
67  				if (eq.length > 1) { // first one is main predicate
68  					equivalent = new URI[eq.length - 1];
69  					for (int i = 1; i < eq.length; i++) {
70  						equivalent[i - 1] = getValueFactory().createURI(eq[i]);
71  					}
72  				}
73  				if (getter.isAnnotationPresent(inverseOf.class)) {
74  					String[] inv = ann.value();
75  					inverseOf = new URI[inv.length];
76  					for (int i = 0; i < inv.length; i++) {
77  						inverseOf[i] = getValueFactory().createURI(inv[i]);
78  					}
79  				}
80  			} else if (getter.isAnnotationPresent(inverseOf.class)) {
81  				String[] inv = ann.value();
82  				if (inv.length > 1) { // first one is main predicate
83  					inverseOf = new URI[inv.length - 1];
84  					for (int i = 1; i < inv.length; i++) {
85  						inverseOf[i - 1] = getValueFactory().createURI(inv[i]);
86  					}
87  				}
88  			}
89  		}
90  		return super.setPropertyDescriptor(property);
91  	}
92  
93  	@Override
94  	protected PropertyChanger getPropertyChanger() {
95  		final URI pred = getPredicate();
96  		final URI[] equivalent = this.equivalent;
97  		final URI[] inverseOf = this.inverseOf;
98  		if (equivalent == null && inverseOf == null)
99  			return super.getPropertyChanger();
100 		return new PropertyChanger(pred, getOneOf()) {
101 			@Override
102 			public void add(ContextAwareConnection conn, Resource subj,
103 					Value obj) throws RepositoryException {
104 				super.add(conn, subj, obj);
105 				if (equivalent != null) {
106 					for (URI eq : equivalent) {
107 						conn.add(subj, eq, obj);
108 					}
109 				}
110 				if (inverseOf != null) {
111 					for (URI inv : inverseOf) {
112 						conn.add((Resource) obj, inv, subj);
113 					}
114 				}
115 			}
116 
117 			@Override
118 			public void remove(ContextAwareConnection conn, Resource subj,
119 					Value obj) throws RepositoryException {
120 				super.remove(conn, subj, obj);
121 				if (equivalent != null) {
122 					for (URI eq : equivalent) {
123 						conn.remove(subj, eq, obj);
124 					}
125 				}
126 				if (inverseOf != null) {
127 					for (URI inv : inverseOf) {
128 						conn.remove((Resource) obj, inv, subj);
129 					}
130 				}
131 			}
132 
133 		};
134 	}
135 
136 }