/******************************************************************************* * Copyright (c) 2009, 2010 Fraunhofer IWU and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Fraunhofer IWU - initial API and implementation *******************************************************************************/ package net.enilink.komma.model.base; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import net.enilink.komma.model.IContentHandler; import net.enilink.komma.model.IModel; import net.enilink.komma.model.IModelSet; import net.enilink.komma.model.IURIConverter; import net.enilink.komma.core.URI; /** * An extensible implementation of a resource factory registry. */ public class ModelFactoryRegistry implements IModel.Factory.Registry { /** * The protocol map. */ protected Map<String, Object> protocolToFactoryMap = new HashMap<String, Object>(); /** * The extension map. */ protected Map<String, Object> extensionToFactoryMap = new HashMap<String, Object>(); /** * The content type identifier map. */ protected Map<String, Object> contentTypeIdentifierToFactoryMap = new HashMap<String, Object>(); /** * Returns the model factory appropriate for the given URI. * <p> * This implementation does the * {@link IModel.Factory.Registry#getFactory(URI) * typical} thing. It will delegate to * {@link #delegatedGetFactory(URI, String)} in the case that the typical * behavior doesn't produce a result; clients are encouraged to override * that method only. * </p> * * @param uri * the URI. * @return the resource factory appropriate for the given URI. * @see org.eclipse.emf.ecore.resource.ResourceSet#createModel(URI) */ public IModel.Factory getFactory(URI uri) { return convert(getFactory(uri, protocolToFactoryMap, extensionToFactoryMap, contentTypeIdentifierToFactoryMap, IContentHandler.UNSPECIFIED_CONTENT_TYPE, true)); } /** * Returns the resource factory appropriate for the given URI. * <p> * This implementation does the * {@link IModel.Factory.Registry#getFactory(URI, String) * typical} thing. It will delegate to * {@link #delegatedGetFactory(URI, String)} in the case that the typical * behavior doesn't produce a result; clients are encouraged to override * that method only. * </p> * * @param uri * the URI. * @return the resource factory appropriate for the given URI. * @see IModelSet#createModel(URI) */ public IModel.Factory getFactory(URI uri, String contentType) { return convert(getFactory(uri, protocolToFactoryMap, extensionToFactoryMap, contentTypeIdentifierToFactoryMap, contentType, true)); } public static IModel.Factory convert(Object ontModelFactory) { return ontModelFactory instanceof IModel.Factory.IDescriptor ? ((IModel.Factory.IDescriptor) ontModelFactory) .createFactory() : (IModel.Factory) ontModelFactory; } protected Object getFactory(URI uri, Map<String, Object> protocolToFactoryMap, Map<String, Object> extensionToFactoryMap, Map<String, Object> contentTypeIdentifierToFactoryMap, String contentTypeIdentifier, boolean delegate) { Object modelFactory = null; if (!protocolToFactoryMap.isEmpty()) { modelFactory = protocolToFactoryMap.get(uri.scheme()); } if (modelFactory == null) { boolean extensionToFactoryMapIsEmpty = extensionToFactoryMap .isEmpty(); if (!extensionToFactoryMapIsEmpty) { modelFactory = extensionToFactoryMap .get(uri.fileExtension()); } if (modelFactory == null) { boolean contentTypeIdentifierToFactoryMapIsEmpty = contentTypeIdentifierToFactoryMap .isEmpty(); if (!contentTypeIdentifierToFactoryMapIsEmpty) { if (IContentHandler.UNSPECIFIED_CONTENT_TYPE .equals(contentTypeIdentifier)) { contentTypeIdentifier = getContentTypeIdentifier(uri); } if (contentTypeIdentifier != null) { modelFactory = contentTypeIdentifierToFactoryMap .get(contentTypeIdentifier); } } if (modelFactory == null) { if (!extensionToFactoryMapIsEmpty) { modelFactory = extensionToFactoryMap .get(IModel.Factory.Registry.DEFAULT_EXTENSION); } if (modelFactory == null) { if (!contentTypeIdentifierToFactoryMapIsEmpty) { modelFactory = contentTypeIdentifierToFactoryMap .get(IModel.Factory.Registry.DEFAULT_CONTENT_TYPE_IDENTIFIER); } if (modelFactory == null && delegate) { modelFactory = delegatedGetFactory(uri, contentTypeIdentifier); } } } } } return modelFactory; } protected String getContentTypeIdentifier(URI uri) { try { Map<String, ?> contentDescription = getURIConverter() .contentDescription(uri, getContentDescriptionOptions()); return (String) contentDescription .get(IContentHandler.CONTENT_TYPE_PROPERTY); } catch (IOException e) { return null; } } /** * Returns the URI converter that's used to * {@link URIConverter#contentDescription(URI, Map) compute} the content * type identifier. * * @return the URI converter that's used to compute the content type * identifier. */ protected IURIConverter getURIConverter() { return null; } /** * A constant read only map of * {@link URIConverter#contentDescription(URI, Map) options} used to request * just the {@link IContentHandler#CONTENT_TYPE_PROPERTY content type}. */ protected static final Map<?, ?> CONTENT_DESCRIPTION_OPTIONS; static { Map<Object, Object> contentDescriptionOptions = new HashMap<Object, Object>(); Set<String> requestedProperties = new HashSet<String>(); requestedProperties.add(IContentHandler.CONTENT_TYPE_PROPERTY); contentDescriptionOptions .put(IContentHandler.OPTION_REQUESTED_PROPERTIES, requestedProperties); CONTENT_DESCRIPTION_OPTIONS = Collections .unmodifiableMap(contentDescriptionOptions); } /** * Returns the default options used to * {@link URIConverter#contentDescription(URI, Map) compute} the content * type identifier. * * @return the default options used to compute the content type identifier. */ protected Map<?, ?> getContentDescriptionOptions() { return CONTENT_DESCRIPTION_OPTIONS; } /** * Returns the resource factory appropriate for the given URI and * {@link IContentHandler#CONTENT_TYPE_PROPERTY content type identifier}, * when standard alternatives fail. * <p> * This implementation calls {@link #delegatedGetFactory(URI)}; clients are * encouraged to override it. * </p> * * @param uri * the URI. * @param contentTypeIdentifier * the {@link IContentHandler#CONTENT_TYPE_PROPERTY content type * identifier}. * @return the resource factory appropriate for the given URI and content * type identifier. * @see #getFactory(URI) */ protected IModel.Factory delegatedGetFactory(URI uri, String contentTypeIdentifier) { return null; } /* * Javadoc copied from interface. */ public Map<String, Object> getExtensionToFactoryMap() { return extensionToFactoryMap; } /* * Javadoc copied from interface. */ public Map<String, Object> getProtocolToFactoryMap() { return protocolToFactoryMap; } /* * Javadoc copied from interface. */ public Map<String, Object> getContentTypeToFactoryMap() { return contentTypeIdentifierToFactoryMap; } }