/** * Copyright (c) 2007-2012 IBM Corporation 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: * IBM - Initial API and implementation */ package org.eclipse.emf.ecore.resource.impl; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.ContentHandler; public class PlatformContentHandlerImpl extends ContentHandlerImpl { private static final Map<String, QualifiedName> PROPERTY_CACHE = new HashMap<String, QualifiedName>(); /** * Returns the property name converted to a qualified name. * @param property the property to convert. * @return the property name converted to a qualified name. */ protected QualifiedName getQualifiedName(String property) { QualifiedName result = PROPERTY_CACHE.get(property); if (result == null) { int index = property.lastIndexOf(":"); if (index == -1) { result = new QualifiedName(null, property); } else { result = new QualifiedName(property.substring(0, index), property.substring(index + 1)); } PROPERTY_CACHE.put(property, result); } return result; } /** * Returns the given property's Eclipse value converted to EMF's corresponding basic value. * @param qualifiedName the name of the property for which this value applies. * @param value the value to convert. * @return the given property's Eclipse value converted to EMF's corresponding basic value. */ protected Object getDescriptionValue(QualifiedName qualifiedName, Object value) { if (value == null) { return null; } else if (IContentDescription.BYTE_ORDER_MARK.equals(qualifiedName)) { for (ByteOrderMark byteOrderMarker : ContentHandler.ByteOrderMark.values()) { if (value == byteOrderMarker.bytes()) { return byteOrderMarker; } } return null; } else { return value; } } /** * This implementation delegates to the platform's content description support, */ @Override public Map<String, Object> contentDescription(URI uri, InputStream inputStream, Map<?, ?> options, Map<Object, Object> context) throws IOException { IContentDescription contentDescription; try { if (uri.isPlatformResource() && PlatformResourceURIHandlerImpl.workspaceRoot != null) { contentDescription = PlatformResourceURIHandlerImpl.WorkbenchHelper.getContentDescription(uri.toPlatformString(true), options); } else { contentDescription = Platform.getContentTypeManager().getDescriptionFor(inputStream, uri.lastSegment(), IContentDescription.ALL); } } catch (IOException exception) { return super.contentDescription(uri, inputStream, options, context); } if (contentDescription == null) { return INVALID_CONTENT_DESCRIPTION; } else { Map<String, Object> result = createContentDescription(ContentHandler.Validity.VALID); result.put(ContentHandler.CONTENT_TYPE_PROPERTY, contentDescription.getContentType().getId()); Set<String> requestedProperties = getRequestedProperties(options); if (requestedProperties == null) { Object bom = getDescriptionValue(IContentDescription.BYTE_ORDER_MARK, contentDescription.getProperty(IContentDescription.BYTE_ORDER_MARK)); if (bom != null) { result.put(ContentHandler.BYTE_ORDER_MARK_PROPERTY, bom); } Object charset = getDescriptionValue(IContentDescription.CHARSET, contentDescription.getProperty(IContentDescription.CHARSET)); if (charset != null) { result.put(ContentHandler.CHARSET_PROPERTY, charset); } Object lineDelimiter = getDescriptionValue(Describer.LINE_DELIMITER, contentDescription.getProperty(Describer.LINE_DELIMITER)); if (lineDelimiter == null) { lineDelimiter = getLineDelimiter(uri, inputStream, options, context); } if (lineDelimiter != null) { result.put(ContentHandler.LINE_DELIMITER_PROPERTY, lineDelimiter); } } else { for (String property : requestedProperties) { if (ContentHandler.LINE_DELIMITER_PROPERTY.equals(property)) { Object lineDelimiter = getDescriptionValue(Describer.LINE_DELIMITER, contentDescription.getProperty(Describer.LINE_DELIMITER)); if (lineDelimiter == null) { lineDelimiter = getLineDelimiter(uri, inputStream, options, context); } if (lineDelimiter != null) { result.put(property, lineDelimiter); } } else { QualifiedName qualifiedName = getQualifiedName(property); if (qualifiedName != null) { Object value = getDescriptionValue(qualifiedName, contentDescription.getProperty(qualifiedName)); if (value != null) { result.put(property, value); } } } } } return result; } } /** * This implementation only gets called when platform's content describer throws an exception, i.e., when the resource doesn't exist. * For {@link URI#isPlatformResource() platform resource URIs}, it determines the character set from the workspace. * @since 2.9 */ @Override protected String getCharset(URI uri, InputStream inputStream, Map<?, ?> options, Map<Object, Object> context) throws IOException { if (uri.isPlatformResource() && PlatformResourceURIHandlerImpl.workspaceRoot != null) { return PlatformResourceURIHandlerImpl.WorkbenchHelper.getCharset(uri.toPlatformString(true), options); } else { return super.getCharset(uri, inputStream, options, context); } } /** * This implementation only gets called when platform's content describer throws an exception, i.e., when the resource doesn't exist. * For {@link URI#isPlatformResource() platform resource URIs}, it determines the line delimiter from the project/workspace preferences. * @since 2.9 */ @Override protected String getLineDelimiter(URI uri, InputStream inputStream, Map<?, ?> options, Map<Object, Object> context) throws IOException { if (uri.isPlatformResource() && PlatformResourceURIHandlerImpl.workspaceRoot != null) { return PlatformResourceURIHandlerImpl.WorkbenchHelper.getLineDelimiter(uri.toPlatformString(true), options); } else { return super.getCharset(uri, inputStream, options, context); } } }