/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.jena.datatypes; import java.net.URI; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import org.apache.jena.datatypes.xsd.XSDDatatype ; import org.apache.jena.datatypes.xsd.impl.RDFLangString ; import org.apache.jena.datatypes.xsd.impl.XMLLiteralType ; import org.apache.jena.shared.impl.JenaParameters ; /** * The TypeMapper provides a global registry of known datatypes. * The datatypes can be retrieved by their URI or from the java class * that is used to represent them. */ // Added extended set of class mappings and getTypeByClass // as suggested by Thorsten Moeller. der 8/5/09 public class TypeMapper { //======================================================================= // Statics /** * Return the single global instance of the TypeMapper. * Done this way rather than simply making the static * field directly accessible to allow us to dynamically * replace the entire mapper table if needed. */ public static TypeMapper getInstance() { return theTypeMap; } public static void setInstance(TypeMapper typeMapper) { theTypeMap = typeMapper ; } /** * The single global instance of the TypeMapper */ private static TypeMapper theTypeMap; /** * Static initializer. Adds builtin datatypes to the mapper. */ static { reset() ; } public static void reset() { theTypeMap = new TypeMapper(); theTypeMap.registerDatatype(XMLLiteralType.theXMLLiteralType); theTypeMap.registerDatatype(RDFLangString.rdfLangString) ; XSDDatatype.loadXSDSimpleTypes(theTypeMap); // add primitive types theTypeMap.classToDT.put(float.class, theTypeMap.classToDT.get(Float.class)); theTypeMap.classToDT.put(double.class, theTypeMap.classToDT.get(Double.class)); theTypeMap.classToDT.put(int.class, theTypeMap.classToDT.get(Integer.class)); theTypeMap.classToDT.put(long.class, theTypeMap.classToDT.get(Long.class)); theTypeMap.classToDT.put(short.class, theTypeMap.classToDT.get(Short.class)); theTypeMap.classToDT.put(byte.class, theTypeMap.classToDT.get(Byte.class)); theTypeMap.classToDT.put(boolean.class, theTypeMap.classToDT.get(Boolean.class)); // add missing character types theTypeMap.classToDT.put(char.class, theTypeMap.classToDT.get(String.class)); theTypeMap.classToDT.put(Character.class, theTypeMap.classToDT.get(String.class)); // add mapping for URL class theTypeMap.classToDT.put(URL.class, theTypeMap.classToDT.get(URI.class)); } public TypeMapper() { super(); } //======================================================================= // Variables /** Map from uri to datatype */ private final HashMap<String, RDFDatatype> uriToDT = new HashMap<>(); /** Map from java class to datatype */ private final HashMap<Class<?>, RDFDatatype> classToDT = new HashMap<>(); //======================================================================= // Methods /** * Version of getTypeByName which will treat unknown URIs as typed * literals but with just the default implementation * * @param uri the URI of the desired datatype * @return Datatype the datatype definition * registered at uri, if there is no such registered type it * returns a new instance of the default datatype implementation, if the * uri is null it returns null (indicating a plain RDF literal). */ public RDFDatatype getSafeTypeByName(final String uri) { RDFDatatype dtype = uriToDT.get(uri); if (dtype == null) { if (uri == null) { // Plain literal return null; } else { // Unknown datatype if (JenaParameters.enableSilentAcceptanceOfUnknownDatatypes) { dtype = new BaseDatatype(uri); registerDatatype(dtype); } else { throw new DatatypeFormatException( "Attempted to created typed literal using an unknown datatype - " + uri); } } } return dtype; } /** * Lookup a known datatype. An unkown datatype or a datatype with uri null * will return null will mean that the value will be treated as a old-style plain literal. * * @param uri the URI of the desired datatype * @return Datatype the datatype definition of null if not known. */ public RDFDatatype getTypeByName(final String uri) { return uriToDT.get(uri); } /** * Method getTypeByValue. Look up a datatype suitable for representing * the given java value object. * * @param value a value instance to be represented * @return Datatype a datatype whose value space matches the java class * of <code>value</code> */ public RDFDatatype getTypeByValue(final Object value) { return classToDT.get(value.getClass()); } /** * List all the known datatypes */ public Iterator<RDFDatatype> listTypes() { return uriToDT.values().iterator(); } /** * Look up a datatype suitable for representing instances of the * given Java class. * * @param clazz a Java class to be represented * @return a datatype whose value space matches the given java class */ public RDFDatatype getTypeByClass(final Class<?> clazz) { return classToDT.get(clazz); } /** * Register a new datatype */ public void registerDatatype(final RDFDatatype type) { uriToDT.put(type.getURI(), type); final Class<?> jc = type.getJavaClass(); if (jc != null) { classToDT.put(jc, type); } } }