Copyright (c) 2004, 2017 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Mickael Istria (Red Hat Inc.) - [263316] regexp for file association
/******************************************************************************* * Copyright (c) 2004, 2017 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Mickael Istria (Red Hat Inc.) - [263316] regexp for file association *******************************************************************************/
package org.eclipse.core.internal.content; import java.util.*; import org.eclipse.core.internal.runtime.RuntimeLog; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.preferences.*; import org.eclipse.osgi.util.NLS; import org.osgi.service.prefs.BackingStoreException;
This class is a sidekick for ContentTypeManager that provides mechanisms for creating content types from the extension registry (which ContentTypeManager is oblivious to).
/** * This class is a sidekick for ContentTypeManager that provides mechanisms for * creating content types from the extension registry (which ContentTypeManager * is oblivious to). */
public class ContentTypeBuilder { public static final String PT_CONTENTTYPES = "contentTypes"; //$NON-NLS-1$ private ContentTypeCatalog catalog; private static String getUniqueId(String namespace, String baseTypeId) { if (baseTypeId == null) return null; int separatorPosition = baseTypeId.lastIndexOf('.'); // base type is defined in the same namespace if (separatorPosition == -1) baseTypeId = namespace + '.' + baseTypeId; return baseTypeId; } private static QualifiedName parseQualifiedName(String namespace, String value) { if (value == null) return null; int separatorPosition = value.lastIndexOf('.'); // base type is defined in the same namespace if (separatorPosition == -1) return new QualifiedName(namespace, value); if (separatorPosition == 0 || separatorPosition == value.length() - 1) // invalid value specified return null; namespace = value.substring(0, separatorPosition); String simpleValue = value.substring(separatorPosition + 1); return new QualifiedName(namespace, simpleValue); } private static byte parsePriority(String priority) { if (priority == null) return ContentType.PRIORITY_NORMAL; if (priority.equals("high")) //$NON-NLS-1$ return ContentType.PRIORITY_HIGH; if (priority.equals("low")) //$NON-NLS-1$ return ContentType.PRIORITY_LOW; if (!priority.equals("normal")) //$NON-NLS-1$ return ContentType.PRIORITY_NORMAL; //TODO: should log - INVALID PRIORITY return ContentType.PRIORITY_NORMAL; } protected ContentTypeBuilder(ContentTypeCatalog catalog) { this.catalog = catalog; } private void addFileAssociation(IConfigurationElement fileAssociationElement, ContentType target) { String[] fileNames = Util.parseItems(fileAssociationElement.getAttribute("file-names")); //$NON-NLS-1$ for (String fileName : fileNames) target.internalAddFileSpec(fileName, IContentType.FILE_NAME_SPEC | ContentType.SPEC_PRE_DEFINED); String[] fileExtensions = Util.parseItems(fileAssociationElement.getAttribute("file-extensions")); //$NON-NLS-1$ for (String fileExtension : fileExtensions) target.internalAddFileSpec(fileExtension, IContentType.FILE_EXTENSION_SPEC | ContentType.SPEC_PRE_DEFINED); String[] filePatterns = Util.parseItems(fileAssociationElement.getAttribute("file-patterns")); //$NON-NLS-1$ for (String filePattern : filePatterns) target.internalAddFileSpec(filePattern, IContentType.FILE_PATTERN_SPEC | ContentType.SPEC_PRE_DEFINED); }
Builds all content types found in the extension registry.
/** * Builds all content types found in the extension registry. */
public void buildCatalog(IScopeContext context) { IConfigurationElement[] allContentTypeCEs = getConfigurationElements(); for (IConfigurationElement allContentTypeCE : allContentTypeCEs) if (allContentTypeCE.getName().equals("content-type")) //$NON-NLS-1$ registerContentType(allContentTypeCE); for (String id : ContentTypeManager.getUserDefinedContentTypeIds(context)) { IEclipsePreferences node = context.getNode(id); catalog.addContentType(ContentType.createContentType(catalog, id, node.get(ContentType.PREF_USER_DEFINED__NAME, ContentType.EMPTY_STRING), (byte) 0, new String[0], new String[0], new String[0], node.get(ContentType.PREF_USER_DEFINED__BASE_TYPE_ID, null), null, Collections.emptyMap(), null)); } for (IConfigurationElement allContentTypeCE : allContentTypeCEs) if (allContentTypeCE.getName().equals("file-association")) //$NON-NLS-1$ registerFileAssociation(allContentTypeCE); applyPreferences(); }
Applies any existing preferences to content types as a batch operation.
/** * Applies any existing preferences to content types as a batch operation. */
private void applyPreferences() { try { final ContentTypeCatalog localCatalog = catalog; final IEclipsePreferences root = localCatalog.getManager().getPreferences(); root.accept(new IPreferenceNodeVisitor() { @Override public boolean visit(IEclipsePreferences node) { if (node == root) return true; ContentType contentType = localCatalog.internalGetContentType(node.name()); if (contentType != null) contentType.processPreferences(node); // content type nodes don't have any children anyway return false; } }); } catch (BackingStoreException bse) { ContentType.log(ContentMessages.content_errorLoadingSettings, bse); } }
Throws:
  • CoreException – if mandatory attributes are missing in the markup
/** * @throws CoreException if mandatory attributes are missing in the markup */
private ContentType createContentType(IConfigurationElement contentTypeCE) throws CoreException { String namespace = contentTypeCE.getContributor().getName(); String simpleId = contentTypeCE.getAttribute("id"); //$NON-NLS-1$ String name = contentTypeCE.getAttribute("name"); //$NON-NLS-1$ if (simpleId == null) missingMandatoryAttribute(ContentMessages.content_missingIdentifier, namespace); String uniqueId; if (simpleId.lastIndexOf('.') == -1) uniqueId = namespace + '.' + simpleId; else uniqueId = simpleId; if (name == null) missingMandatoryAttribute(ContentMessages.content_missingName, uniqueId); byte priority = parsePriority(contentTypeCE.getAttribute("priority")); //$NON-NLS-1$ ); String[] fileNames = Util.parseItems(contentTypeCE.getAttribute("file-names")); //$NON-NLS-1$ String[] fileExtensions = Util.parseItems(contentTypeCE.getAttribute("file-extensions")); //$NON-NLS-1$ String[] filePatterns = Util.parseItems(contentTypeCE.getAttribute("file-patterns")); //$NON-NLS-1$ String baseTypeId = getUniqueId(namespace, contentTypeCE.getAttribute("base-type")); //$NON-NLS-1$ String aliasTargetTypeId = getUniqueId(namespace, contentTypeCE.getAttribute("alias-for")); //$NON-NLS-1$ IConfigurationElement[] propertyCEs = null; Map<QualifiedName, String> defaultProperties = null; if ((propertyCEs = contentTypeCE.getChildren("property")).length > 0) { //$NON-NLS-1$ defaultProperties = new HashMap<>(); for (IConfigurationElement propertyCE : propertyCEs) { String defaultValue = propertyCE.getAttribute("default"); //$NON-NLS-1$ if (defaultValue == null) // empty string means: default value is null defaultValue = ""; //$NON-NLS-1$ String propertyKey = propertyCE.getAttribute("name"); //$NON-NLS-1$ QualifiedName qualifiedKey = parseQualifiedName(namespace, propertyKey); if (qualifiedKey == null) { if (ContentTypeManager.DEBUGGING) { String message = NLS.bind(ContentMessages.content_invalidProperty, propertyKey, getUniqueId(namespace, simpleId)); ContentType.log(message, null); } continue; } defaultProperties.put(qualifiedKey, defaultValue); } } String defaultCharset = contentTypeCE.getAttribute("default-charset"); //$NON-NLS-1$ if (defaultCharset != null) if (defaultProperties == null) defaultProperties = Collections.singletonMap(IContentDescription.CHARSET, defaultCharset); else if (!defaultProperties.containsKey(IContentDescription.CHARSET)) defaultProperties.put(IContentDescription.CHARSET, defaultCharset); return ContentType.createContentType(catalog, uniqueId, name, priority, fileExtensions, fileNames, filePatterns, baseTypeId, aliasTargetTypeId, defaultProperties, contentTypeCE); } // Store this around for performance private final static IConfigurationElement[] emptyConfArray = new IConfigurationElement[0];
Gets configuration elements for both "backward compatible" extension point org.eclipse.core.runtime.contentTypes and "new" extension point controlled by this plugin: org.eclipse.core.contenttype.contentTypes
/** * Gets configuration elements for both "backward compatible" extension point * org.eclipse.core.runtime.contentTypes * and "new" extension point controlled by this plugin: * org.eclipse.core.contenttype.contentTypes */
protected IConfigurationElement[] getConfigurationElements() { IExtensionRegistry registry = RegistryFactory.getRegistry(); if (registry == null) return emptyConfArray; IConfigurationElement[] oldConfigElements = emptyConfArray; IConfigurationElement[] newConfigElements = emptyConfArray; // "old" extension point IExtensionPoint oldPoint = registry.getExtensionPoint(IContentConstants.RUNTIME_NAME, PT_CONTENTTYPES); if (oldPoint != null) oldConfigElements = oldPoint.getConfigurationElements(); // "new" extension point IExtensionPoint newPoint = registry.getExtensionPoint(IContentConstants.CONTENT_NAME, PT_CONTENTTYPES); if (newPoint != null) newConfigElements = newPoint.getConfigurationElements(); IConfigurationElement[] allContentTypeCEs = new IConfigurationElement[oldConfigElements.length + newConfigElements.length]; System.arraycopy(oldConfigElements, 0, allContentTypeCEs, 0, oldConfigElements.length); System.arraycopy(newConfigElements, 0, allContentTypeCEs, oldConfigElements.length, newConfigElements.length); return allContentTypeCEs; } private void missingMandatoryAttribute(String messageKey, String argument) throws CoreException { String message = NLS.bind(messageKey, argument); throw new CoreException(new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, null)); } private void registerContentType(IConfigurationElement contentTypeCE) { try { ContentType contentType = createContentType(contentTypeCE); catalog.addContentType(contentType); } catch (CoreException e) { // failed validation RuntimeLog.log(e.getStatus()); } } /* Adds extra file associations to existing content types. If the content * type has not been added, the file association is ignored. */ private void registerFileAssociation(IConfigurationElement fileAssociationElement) { //TODO: need to ensure the config. element is valid String contentTypeId = getUniqueId(fileAssociationElement.getContributor().getName(), fileAssociationElement.getAttribute("content-type")); //$NON-NLS-1$ ContentType target = catalog.internalGetContentType(contentTypeId); if (target == null) return; addFileAssociation(fileAssociationElement, target); } }