View Javadoc

1   /*	
2   	Copyright 2007-2014 Fraunhofer IGD, http://www.igd.fraunhofer.de
3   	Fraunhofer-Gesellschaft - Institute for Computer Graphics Research
4   	
5   	See the NOTICE file distributed with this work for additional 
6   	information regarding copyright ownership
7   	
8   	Licensed under the Apache License, Version 2.0 (the "License");
9   	you may not use this file except in compliance with the License.
10  	You may obtain a copy of the License at
11  	
12  	  http://www.apache.org/licenses/LICENSE-2.0
13  	
14  	Unless required by applicable law or agreed to in writing, software
15  	distributed under the License is distributed on an "AS IS" BASIS,
16  	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  	See the License for the specific language governing permissions and
18  	limitations under the License.
19   */
20  package org.universAAL.middleware.owl;
21  
22  import java.util.ArrayList;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.universAAL.middleware.rdf.Resource;
28  import org.universAAL.middleware.rdf.Variable;
29  import org.universAAL.middleware.util.MatchLogEntry;
30  
31  /**
32   * Implementation of OWL HasValue Restriction: it contains all individuals that
33   * are connected by the specified property to the given individual.
34   * 
35   * @author Carsten Stockloew
36   */
37  public final class HasValueRestriction extends PropertyRestriction {
38  
39      public static final String MY_URI = uAAL_VOCABULARY_NAMESPACE
40  	    + "HasValueRestriction";
41  
42      public static final String PROP_OWL_HAS_VALUE = OWL_NAMESPACE + "hasValue";
43  
44      /** Standard constructor for exclusive use by serializers. */
45      HasValueRestriction() {
46      }
47  
48      public HasValueRestriction(String propURI, Object o) {
49  	if (propURI == null || o == null)
50  	    throw new NullPointerException();
51  	setOnProperty(propURI);
52  	if (o instanceof String && isQualifiedName((String) o))
53  	    o = new Resource((String) o);
54  	super.setProperty(PROP_OWL_HAS_VALUE, o);
55      }
56  
57      /**
58       * @see org.universAAL.middleware.owl.PropertyRestriction#getClassURI()
59       */
60      public String getClassURI() {
61  	return MY_URI;
62      }
63  
64      public Object getConstraint() {
65  	return getProperty(PROP_OWL_HAS_VALUE);
66      }
67  
68      /** @see org.universAAL.middleware.owl.TypeExpression#copy() */
69      public TypeExpression copy() {
70  	return copyTo(new HasValueRestriction());
71      }
72  
73      /** Helper function for {@link #checkValue(Object, HashMap)}. */
74      private List resolveVariables(List l, HashMap context) {
75  	List result = new ArrayList(l.size());
76  	for (int i = 0; i < l.size(); i++)
77  	    result.add(Variable.resolveVarRef(l.get(i), context));
78  	return result;
79      }
80  
81      /** Helper function for {@link #checkValue(Object, HashMap)}. */
82      // -1 -> incompatible; 0 -> equal; 1 -> compatible
83      private int checkValueLists(List first, List second, HashMap context) {
84  	if (first.size() != second.size())
85  	    return -1;
86  	HashMap aux = new HashMap(second.size());
87  	for (int i = 0; i < first.size(); i++) {
88  	    Object o = first.get(i);
89  	    if (o instanceof Variable) {
90  		if (((Variable) o).getMinCardinality() > 1)
91  		    return -1;
92  		boolean found = false;
93  		for (Iterator j = second.iterator(); !found && j.hasNext();) {
94  		    Object oo = j.next();
95  		    if (oo instanceof Variable) {
96  			// check that the type in 'oo' is a subclass of the type
97  			// in 'o'
98  			boolean found2 = false;
99  			String superClassName = ((Variable) o)
100 				.getParameterType();
101 			String subClassName = ((Variable) oo)
102 				.getParameterType();
103 
104 			if (superClassName.equals(subClassName)) {
105 			    found2 = true;
106 			} else {
107 			    OntClassInfo sub = OntologyManagement.getInstance()
108 				    .getOntClassInfo(subClassName);
109 			    if (sub != null) {
110 				if (sub.hasSuperClass(superClassName, true))
111 				    found2 = true;
112 			    }
113 			}
114 
115 			if (found2) {
116 			    aux.put(((Variable) o).getURI(), oo);
117 			    j.remove();
118 			    found = true;
119 			}
120 		    } else {
121 			if (ManagedIndividual.checkMembership(
122 				((Variable) o).getParameterType(), oo)) {
123 			    aux.put(((Variable) o).getURI(), oo);
124 			    j.remove();
125 			    found = true;
126 			}
127 		    }
128 		}
129 		if (!found)
130 		    return -1;
131 	    } else if (!second.remove(o)) {
132 		boolean found = false;
133 		for (Iterator j = second.iterator(); !found && j.hasNext();) {
134 		    Object oo = j.next();
135 		    if (oo instanceof Variable) {
136 			if (((Variable) oo).getMinCardinality() > 1)
137 			    return -1;
138 			if (ManagedIndividual.checkMembership(
139 				((Variable) oo).getParameterType(), o)) {
140 			    aux.put(((Variable) oo).getURI(), o);
141 			    j.remove();
142 			    found = true;
143 			}
144 		    }
145 		}
146 		if (!found)
147 		    return -1;
148 	    }
149 	}
150 	if (!second.isEmpty())
151 	    return -1;
152 	if (!aux.isEmpty())
153 	    if (context == null)
154 		return -1;
155 	    else {
156 		for (Iterator i = aux.keySet().iterator(); i.hasNext();) {
157 		    Object key = i.next();
158 		    context.put(key, aux.get(key));
159 		}
160 		return 1;
161 	    }
162 	return 0;
163     }
164 
165     /** Helper function for {@link #hasMember(Object, HashMap)}. */
166     // -1 -> incompatible; 0 -> equal; 1 -> compatible
167     private int checkValue(Object value, HashMap context) {
168 	if (value == null)
169 	    return 1;
170 
171 	Object myValue = props.get(PROP_OWL_HAS_VALUE);
172 	if (myValue == null)
173 	    // no value restriction => all values are compatible
174 	    return 1;
175 
176 	if (myValue instanceof List)
177 	    myValue = resolveVariables((List) myValue, context);
178 	else {
179 	    List aux = new ArrayList(1);
180 	    aux.add(Variable.resolveVarRef(myValue, context));
181 	    myValue = aux;
182 	}
183 
184 	// if (value == null) {
185 	// if (((List) myValue).size() == 1)
186 	// myValue = ((List) myValue).get(0);
187 	// else
188 	// return -1;
189 	//
190 	// // an optional parameter without any existing and / or default value
191 	// // means that null value is accepted; then we remark that under the
192 	// // condition that this parameter remains null, the null value is
193 	// // acceptable;
194 	// // for this purpose rdf:nil is used. An existing remark means that
195 	// // the above was asserted previously
196 	// if (RDF_EMPTY_LIST.equals(myValue))
197 	// return 0;
198 	// if (myValue instanceof Variable
199 	// && ((Variable) myValue).getMinCardinality() == 0
200 	// && ((Variable) myValue).getDefaultValue() == null) {
201 	// context.put(((Variable) myValue).getURI(), RDF_EMPTY_LIST);
202 	// return 0;
203 	// }
204 	// return -1;
205 	// }
206 
207 	if (value instanceof List)
208 	    value = resolveVariables((List) value, context);
209 	else {
210 	    List aux = new ArrayList(1);
211 	    aux.add(Variable.resolveVarRef(value, context));
212 	    value = aux;
213 	}
214 
215 	return checkValueLists((List) myValue, (List) value, context);
216     }
217 
218     public boolean hasMember(Object member, HashMap context, int ttl,
219 	    List<MatchLogEntry> log) {
220 	// ttl =
221 	checkTTL(ttl);
222 	if (!(member instanceof Resource))
223 	    return member == null;
224 
225 	Object value = ((Resource) member).getProperty(getOnProperty());
226 	if (checkValue(value, context) == -1)
227 	    return false;
228 	return true;
229     }
230 
231     public boolean isDisjointWith(TypeExpression other, HashMap context,
232 	    int ttl, List<MatchLogEntry> log) {
233 	ttl = checkTTL(ttl);
234 	if (!(other instanceof PropertyRestriction))
235 	    return other.isDisjointWith(this, context, ttl, log);
236 
237 	PropertyRestriction r = (PropertyRestriction) other;
238 	Object o = getOnProperty();
239 	if (o == null || !o.equals(r.getOnProperty()))
240 	    return false;
241 
242 	o = r.getProperty(PROP_OWL_HAS_VALUE);
243 	HashMap cloned = (context == null) ? null : (HashMap) context.clone();
244 	switch (checkValue(o, cloned)) {
245 	case -1: // incompatible
246 	    return true;
247 	case 0: // equal
248 	    if (cloned == null || cloned.size() == context.size())
249 		// unconditional equality
250 		return false;
251 	    else
252 		// TODO: because the equality was conditional, there is still a
253 		// chance to return true by adopting complement conditions into
254 		// context
255 		return false;
256 	}
257 
258 	return true;
259     }
260 
261     /** @see org.universAAL.middleware.owl.TypeExpression#isWellFormed() */
262     public boolean isWellFormed() {
263 	return getOnProperty() != null && (hasProperty(PROP_OWL_HAS_VALUE));
264     }
265 
266     public boolean matches(TypeExpression subset, HashMap context, int ttl,
267 	    List<MatchLogEntry> log) {
268 	Object noRes = matchesNonRestriction(subset, context, ttl, log);
269 	if (noRes instanceof Boolean)
270 	    return ((Boolean) noRes).booleanValue();
271 
272 	PropertyRestriction other = (PropertyRestriction) noRes;
273 
274 	if (other instanceof HasValueRestriction) {
275 	    HashMap cloned = (context == null) ? null : (HashMap) context
276 		    .clone();
277 	    Object o = other.getProperty(PROP_OWL_HAS_VALUE);
278 	    switch (checkValue(o, cloned)) {
279 	    case -1:
280 		return false;
281 	    case 0:
282 	    case 1:
283 		synchronize(context, cloned);
284 		return true;
285 	    }
286 	}
287 
288 	return false;
289     }
290 
291     /** @see org.universAAL.middleware.rdf.Resource#setProperty(String, Object) */
292     public boolean setProperty(String propURI, Object o) {
293 	if (o == null || propURI == null || props.containsKey(propURI))
294 	    return false;
295 
296 	// handle this restriction
297 	if (PROP_OWL_HAS_VALUE.equals(propURI)) {
298 	    Object hasVal = getProperty(PROP_OWL_HAS_VALUE);
299 	    if (hasVal != null)
300 		return false;
301 	    // if (!Variable.checkDeserialization(o))
302 	    // return false;
303 	    // hasVarRefAsValue = Variable.isVarRef(o);
304 	    return super.setProperty(PROP_OWL_HAS_VALUE, o);
305 	}
306 
307 	// do not handle other restrictions
308 	if (propMap.containsKey(propURI))
309 	    return false;
310 
311 	// for everything else: call super
312 	return super.setProperty(propURI, o);
313     }
314 }