001 /*
002 * The contents of this file are subject to the Mozilla Public License
003 * Version 1.1 (the "License"); you may not use this file except in
004 * compliance with the License. You may obtain a copy of the License at
005 * http://www.mozilla.org/MPL/
006 *
007 * Software distributed under the License is distributed on an "AS IS" basis,
008 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009 * the specific language governing rights and limitations under the License.
010 *
011 * The Original Code is Protege-2000.
012 *
013 * The Initial Developer of the Original Code is Stanford University. Portions
014 * created by Stanford University are Copyright (C) 2007. All Rights Reserved.
015 *
016 * Protege was developed by Stanford Medical Informatics
017 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
018 * with support from the National Library of Medicine, the National Science
019 * Foundation, and the Defense Advanced Research Projects Agency. Current
020 * information about Protege can be obtained at http://protege.stanford.edu.
021 *
022 */
023
024 package edu.stanford.smi.protegex.owl.model.impl;
025
026 import edu.stanford.smi.protege.model.FrameID;
027 import edu.stanford.smi.protege.model.KnowledgeBase;
028 import edu.stanford.smi.protegex.owl.model.*;
029 import edu.stanford.smi.protegex.owl.model.visitor.OWLModelVisitor;
030 import edu.stanford.smi.protegex.owl.ui.icons.OWLIcons;
031 import org.apache.xerces.xs.XSSimpleTypeDefinition;
032
033 import javax.swing.*;
034 import java.util.HashMap;
035 import java.util.Map;
036 import java.util.regex.Matcher;
037 import java.util.regex.Pattern;
038
039 /**
040 * @author Holger Knublauch <holger@knublauch.com>
041 */
042 public class DefaultRDFSDatatype extends DefaultRDFIndividual implements RDFSDatatype {
043
044
045 public DefaultRDFSDatatype(KnowledgeBase kb, FrameID id) {
046 super(kb, id);
047 }
048
049
050 public DefaultRDFSDatatype() {
051 }
052
053
054 public void accept(OWLModelVisitor visitor) {
055 visitor.visitRDFDatatype(this);
056 }
057
058
059 public boolean equalsStructurally(RDFObject object) {
060 if (object instanceof RDFSDatatype) {
061 RDFSDatatype datatype = (RDFSDatatype) object;
062 return datatype.getURI() == getURI() &&
063 datatype.getMaxExclusive().equalsStructurally(getMaxExclusive()) &&
064 datatype.getMinExclusive().equalsStructurally(getMinExclusive()) &&
065 datatype.getMaxInclusive().equalsStructurally(getMaxInclusive()) &&
066 datatype.getMinInclusive().equalsStructurally(getMinInclusive());
067 }
068 return false;
069 }
070
071
072 public RDFSDatatype getBaseDatatype() {
073 RDFProperty property = XSPNames.getRDFProperty(getOWLModel(), XSPNames.XSP_BASE);
074 if (property != null) {
075 return (RDFSDatatype) getPropertyValue(property);
076 }
077 else {
078 return null; // getBaseDatatypeXSD();
079 }
080 }
081
082 // private RDFSDatatype getBaseDatatypeXSD() {
083 // XSSimpleType simpleType = getXSSimpleType();
084 // if (simpleType != null) {
085 // XSTypeDefinition baseType = simpleType.getBaseType();
086 // if (baseType != null) {
087 // String name = baseType.getName();
088 // String namespace = baseType.getNamespace();
089 // String uri = namespace + "#" + name;
090 // return getOWLModel().getRDFSDatatypeByURI(uri);
091 // }
092 // }
093 // return null;
094 // }
095
096
097 public String getBrowserText() {
098 if (isAnonymous()) {
099 RDFSDatatype baseDatatype = getBaseDatatype();
100 if (baseDatatype != null) {
101 String str = baseDatatype.getBrowserText();
102 String openingBracket = "[";
103 String closingBracket = "]";
104 RDFSLiteral min = getMinInclusive();
105 RDFSLiteral max = getMaxInclusive();
106 if (min == null) {
107 min = getMinExclusive();
108 if (min != null) {
109 openingBracket = "(";
110 if (max == null) {
111 closingBracket = ")";
112 }
113 }
114 }
115 if (max == null) {
116 max = getMaxExclusive();
117 if (max != null) {
118 closingBracket = ")";
119 }
120 }
121 if (max != null || min != null) {
122 str += openingBracket;
123 if (min != null) {
124 str += min.toString();
125 }
126 else {
127 str += "..";
128 }
129 str += ",";
130 if (max != null) {
131 str += max.toString();
132 }
133 else {
134 str += "..";
135 }
136 return str + closingBracket;
137 }
138 else {
139 return "variant of " + baseDatatype.getBrowserText();
140 }
141 }
142 }
143 String bt = super.getBrowserText();
144 if (bt.startsWith(XSDNames.PREFIX)) {
145 return bt.substring(XSDNames.PREFIX.length());
146 }
147 else {
148 return bt;
149 }
150 }
151
152
153 public Object getDefaultValue() {
154 if (equals(getOWLModel().getXSDboolean())) {
155 return Boolean.FALSE;
156 }
157 else if (equals(getOWLModel().getXSDint())) {
158 return new Integer(0);
159 }
160 else if (equals(getOWLModel().getXSDfloat())) {
161 return new Float(0);
162 }
163 else if (equals(getOWLModel().getXSDstring())) {
164 return "";
165 }
166 else {
167 String literal = "";
168 if (isNumericDatatype()) {
169 literal = "0";
170 }
171 return getOWLModel().createRDFSLiteral(literal, this);
172 }
173 }
174
175 // private Number getFacetValue(String facetName) {
176 // XSSimpleType simpleType = getXSSimpleType();
177 // if (simpleType != null) {
178 // XSObjectList list = simpleType.getFacets();
179 // int length = list.getLength();
180 // short kind = getFacetKind(facetName);
181 // for (int i = 0; i < length; i++) {
182 // XSObject object = list.item(i);
183 // if (object instanceof XSFacet) {
184 // XSFacet facet = (XSFacet) object;
185 // if (kind == facet.getFacetKind()) {
186 // String value = facet.getLexicalFacetValue();
187 // return Integer.valueOf(value);
188 // }
189 // }
190 // }
191 // }
192 // return null;
193 // }
194
195
196 private short getFacetKind(String facetName) {
197 if (facetName.equals(XSDNames.Facet.MAX_EXCLUSIVE)) {
198 return XSSimpleTypeDefinition.FACET_MAXEXCLUSIVE;
199 }
200 else if (facetName.equals(XSDNames.Facet.MAX_INCLUSIVE)) {
201 return XSSimpleTypeDefinition.FACET_MAXINCLUSIVE;
202 }
203 else if (facetName.equals(XSDNames.Facet.MIN_EXCLUSIVE)) {
204 return XSSimpleTypeDefinition.FACET_MINEXCLUSIVE;
205 }
206 else if (facetName.equals(XSDNames.Facet.MIN_INCLUSIVE)) {
207 return XSSimpleTypeDefinition.FACET_MININCLUSIVE;
208 }
209 else {
210 return -1;
211 }
212 }
213
214
215 public Icon getIcon() {
216 return isEditable() ?
217 OWLIcons.getImageIcon(OWLIcons.RDF_DATATYPE) :
218 OWLIcons.getReadOnlyIndividualIcon(OWLIcons.getImageIcon(OWLIcons.RDF_DATATYPE));
219 }
220
221
222 private int getIntPropertyValue(String propertyName) {
223 RDFProperty property = getOWLModel().getRDFProperty(propertyName);
224 if (property != null) {
225 Object value = getPropertyValue(property);
226 if (value instanceof Integer) {
227 return ((Integer) value).intValue();
228 }
229 }
230 return -1;
231 }
232
233
234 public int getLength() {
235 return getIntPropertyValue(XSPNames.getName(getOWLModel(), XSPNames.XSP_LENGTH));
236 }
237
238
239 public RDFSLiteral getMaxExclusive() {
240 return getPropertyValueLiteral(XSPNames.getName(getOWLModel(), XSPNames.XSP_MAX_EXCLUSIVE));
241 }
242
243
244 public RDFSLiteral getMaxInclusive() {
245 return getPropertyValueLiteral(XSPNames.getName(getOWLModel(), XSPNames.XSP_MAX_INCLUSIVE));
246 }
247
248
249 public int getMaxLength() {
250 return getIntPropertyValue(XSPNames.getName(getOWLModel(), XSPNames.XSP_MAX_LENGTH));
251 }
252
253
254 public RDFSLiteral getMinExclusive() {
255 return getPropertyValueLiteral(XSPNames.getName(getOWLModel(), XSPNames.XSP_MIN_EXCLUSIVE));
256 }
257
258
259 public RDFSLiteral getMinInclusive() {
260 return getPropertyValueLiteral(XSPNames.getName(getOWLModel(), XSPNames.XSP_MIN_INCLUSIVE));
261 }
262
263
264 public int getMinLength() {
265 return getIntPropertyValue(XSPNames.getName(getOWLModel(), XSPNames.XSP_MIN_LENGTH));
266 }
267
268
269 public String getPattern() {
270 RDFProperty property = XSPNames.getRDFProperty(getOWLModel(), XSPNames.XSP_PATTERN);
271 if (property != null) {
272 Object value = getPropertyValue(property);
273 if (value != null) {
274 return value.toString();
275 }
276 }
277 return null;
278 }
279
280
281 private RDFSLiteral getPropertyValueLiteral(String propertyName) {
282 RDFProperty property = getOWLModel().getRDFProperty(propertyName);
283 if (property != null) {
284 return getPropertyValueLiteral(property);
285 }
286 else {
287 return null;
288 }
289 }
290
291 // private RDFProperty getSimpleTypeLiteralProperty() {
292 // return getOWLModel().getRDFSLabelProperty(); //
293 // }
294
295 // private XSSimpleType getXSSimpleType() {
296 // RDFProperty stlProperty = getSimpleTypeLiteralProperty();
297 // Object value = getPropertyValue(stlProperty);
298 // if (value != null) {
299 // String str = null;
300 // if (value instanceof RDFSLiteral) {
301 // str = ((RDFSLiteral) value).getString();
302 // }
303 // else {
304 // str = value.toString();
305 // }
306 // str = "<?xml version='1.0'?>\n" +
307 // "<xs:schema " +
308 // " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n" +
309 // " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" +
310 // str +
311 // "</xs:schema>";
312 // XMLGrammarPreparser parser = new XMLGrammarPreparser();
313 // parser.registerPreparser(XMLGrammarDescription.XML_SCHEMA, null);
314 // try {
315 // String uri = "http://dummy." + Math.random();
316 // XMLInputSource source = new XMLInputSource(null, uri, uri, new StringReader(str), null);
317 // XSGrammar xsg = (XSGrammar) parser.preparseGrammar(XMLGrammarDescription.XML_SCHEMA, source);
318 // org.apache.xerces.xs.XSModel xsm = xsg.toXSModel();
319 // XSNamedMap map = xsm.getComponents(XSTypeDefinition.SIMPLE_TYPE);
320 // int numDefs = map.getLength();
321 // if (numDefs > 0) {
322 // XSSimpleType xstype = (XSSimpleType) map.item(0);
323 // return xstype;
324 // }
325 // }
326 // catch (Exception ex) {
327 // }
328 // }
329 // return null;
330 // }
331
332
333 public boolean isNumericDatatype() {
334 String uri = getURI();
335 RDFSDatatype base = getBaseDatatype();
336 if (base != null) {
337 uri = base.getURI();
338 }
339 return XMLSchemaDatatypes.isNumericDatatype(uri);
340 }
341
342
343 public boolean isValidValue(RDFSLiteral object) {
344 RDFSDatatype d = this;
345 RDFSDatatype baseDatatype = getBaseDatatype();
346 if (baseDatatype != null) {
347 d = baseDatatype;
348 }
349 if (!object.getDatatype().equals(d)) {
350 return false;
351 }
352 if (getOWLModel().getXSDstring().equals(d)) {
353 return isValidValueString(object);
354 }
355 else {
356 return isValidValueNumeric(object);
357 }
358 }
359
360
361 private boolean isValidValueNumeric(RDFSLiteral object) {
362 RDFSLiteral minInclusive = getMinInclusive();
363 if (minInclusive != null) {
364 if (object.compareTo(minInclusive) < 0) {
365 return false;
366 }
367 }
368 RDFSLiteral minExclusive = getMinExclusive();
369 if (minExclusive != null) {
370 if (object.compareTo(minExclusive) <= 0) {
371 return false;
372 }
373 }
374 RDFSLiteral maxInclusive = getMaxInclusive();
375 if (maxInclusive != null) {
376 if (object.compareTo(maxInclusive) > 0) {
377 return false;
378 }
379 }
380 RDFSLiteral maxExclusive = getMaxExclusive();
381 if (maxExclusive != null) {
382 if (object.compareTo(maxExclusive) >= 0) {
383 return false;
384 }
385 }
386 return true;
387 }
388
389
390 private boolean isValidValueString(RDFSLiteral object) {
391 String s = object.toString();
392 int l = s.length();
393
394 int length = getLength();
395 if (length >= 0 && length != l) {
396 return false;
397 }
398 int minLength = getMinLength();
399 if (minLength >= 0 && l < minLength) {
400 return false;
401 }
402 int maxLength = getMaxLength();
403 if (maxLength >= 0 && l > maxLength) {
404 return false;
405 }
406 String pattern = getPattern();
407 if (pattern != null) {
408 Pattern p = Pattern.compile(pattern);
409 Matcher matcher = p.matcher(s);
410 if (!matcher.matches()) {
411 return false;
412 }
413 }
414 return true;
415 }
416
417
418 public static Map parse(OWLModel owlModel, String expression) {
419 Map map = new HashMap();
420 if (owlModel.isProtegeMetaOntologyImported()) {
421 int index = 3;
422 while (index < expression.length() &&
423 expression.charAt(index) != '(' &&
424 expression.charAt(index) != '[') {
425 index++;
426 }
427 if (index < expression.length()) {
428 String baseTypeName = expression.substring(0, index).trim();
429 RDFSDatatype datatype = owlModel.getRDFSDatatypeByName(baseTypeName);
430 if (datatype != null) {
431 RDFProperty subDatatypeOfProperty = XSPNames.getRDFProperty(owlModel, XSPNames.XSP_BASE);
432 map.put(subDatatypeOfProperty, datatype);
433 RDFProperty minProperty = null;
434 if (expression.charAt(index) == '(') {
435 minProperty = XSPNames.getRDFProperty(owlModel, XSPNames.XSP_MIN_EXCLUSIVE);
436 }
437 else {
438 minProperty = XSPNames.getRDFProperty(owlModel, XSPNames.XSP_MIN_INCLUSIVE);
439 }
440 String rest = expression.substring(index + 1).trim();
441 int minEnd = 0;
442 while (minEnd < rest.length() &&
443 (Character.isDigit(rest.charAt(minEnd)) || rest.charAt(minEnd) == '.')) {
444 minEnd++;
445 }
446 String min = rest.substring(0, minEnd);
447 if (min.length() > 0 && Character.isDigit(min.charAt(0))) {
448 RDFSLiteral minLiteral = owlModel.createRDFSLiteral(min, datatype);
449 map.put(minProperty, minLiteral);
450 }
451 int maxStart = minEnd;
452 while (maxStart < rest.length() && !Character.isDigit(rest.charAt(maxStart))) {
453 maxStart++;
454 }
455 if (maxStart < rest.length()) {
456 rest = rest.substring(maxStart);
457 int maxEnd = 0;
458 while (maxEnd < rest.length() &&
459 (Character.isDigit(rest.charAt(maxEnd)) || rest.charAt(maxEnd) == '.')) {
460 maxEnd++;
461 }
462 RDFProperty maxProperty = XSPNames.getRDFProperty(owlModel, XSPNames.XSP_MAX_INCLUSIVE);
463 if (rest.endsWith(")")) {
464 maxProperty = XSPNames.getRDFProperty(owlModel, XSPNames.XSP_MAX_EXCLUSIVE);
465 }
466 String max = rest.substring(0, maxEnd);
467 if (max.length() > 0 && Character.isDigit(max.charAt(0))) {
468 RDFSLiteral maxLiteral = owlModel.createRDFSLiteral(max, datatype);
469 map.put(maxProperty, maxLiteral);
470 }
471 }
472 if (map.size() == 1) {
473 return new HashMap();
474 }
475 }
476 }
477 }
478 return map;
479 }
480 }
481