| /******************************************************************************* |
| * Copyright (c) 2006, 2017 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 Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.team.internal.core; |
| |
| import java.util.HashMap; |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.team.core.mapping.IStorageMerger; |
| |
| public class StorageMergerRegistry { |
| |
| private final static String ID_ATTRIBUTE = "id"; //$NON-NLS-1$ |
| private final static String EXTENSIONS_ATTRIBUTE = "extensions"; //$NON-NLS-1$ |
| private final static String CONTENT_TYPE_ID_ATTRIBUTE = "contentTypeId"; //$NON-NLS-1$ |
| private static final String STORAGE_MERGER_EXTENSION_POINT = "storageMergers"; //$NON-NLS-1$ |
| private static final Object STORAGE_MERGER = "storageMerger"; //$NON-NLS-1$ |
| private static final String CONTENT_TYPE_BINDING= "contentTypeBinding"; //$NON-NLS-1$ |
| private static final String STORAGE_MERGER_ID_ATTRIBUTE= "storageMergerId"; //$NON-NLS-1$ |
| |
| private static boolean NORMALIZE_CASE= true; |
| |
| private static StorageMergerRegistry instance; |
| |
| private HashMap<String, Object> fIdMap; // maps ids to datas |
| private HashMap<String, Object> fExtensionMap; // maps extensions to datas |
| private HashMap<IContentType, Object> fContentTypeBindings; // maps content type bindings to datas |
| private boolean fRegistriesInitialized; |
| |
| public static StorageMergerRegistry getInstance() { |
| if (instance == null) { |
| instance = new StorageMergerRegistry(); |
| } |
| return instance; |
| } |
| |
| /** |
| * Returns a stream merger for the given type. |
| * |
| * @param type the type for which to find a stream merger |
| * @return a stream merger for the given type, or <code>null</code> if no |
| * stream merger has been registered |
| */ |
| public IStorageMerger createStreamMerger(String type) { |
| initializeRegistry(); |
| StorageMergerDescriptor descriptor= (StorageMergerDescriptor) search(type); |
| if (descriptor != null) |
| return descriptor.createStreamMerger(); |
| return null; |
| } |
| |
| /** |
| * Returns a stream merger for the given content type. |
| * |
| * @param type the type for which to find a stream merger |
| * @return a stream merger for the given type, or <code>null</code> if no |
| * stream merger has been registered |
| */ |
| public IStorageMerger createStreamMerger(IContentType type) { |
| initializeRegistry(); |
| StorageMergerDescriptor descriptor= (StorageMergerDescriptor) search(type); |
| if (descriptor != null) |
| return descriptor.createStreamMerger(); |
| return null; |
| } |
| |
| private void initializeRegistry() { |
| if (!fRegistriesInitialized) { |
| registerExtensions(); |
| fRegistriesInitialized= true; |
| } |
| } |
| |
| /** |
| * Registers all stream mergers, structure creators, content merge viewers, and structure merge viewers |
| * that are found in the XML plugin files. |
| */ |
| private void registerExtensions() { |
| IExtensionRegistry registry= Platform.getExtensionRegistry(); |
| |
| // collect all IStreamMergers |
| IConfigurationElement[] elements= registry.getConfigurationElementsFor(TeamPlugin.ID, STORAGE_MERGER_EXTENSION_POINT); |
| for (int i= 0; i < elements.length; i++) { |
| IConfigurationElement element= elements[i]; |
| if (STORAGE_MERGER.equals(element.getName())) |
| register(element, new StorageMergerDescriptor(element)); |
| else if (CONTENT_TYPE_BINDING.equals(element.getName())) |
| createBinding(element, STORAGE_MERGER_ID_ATTRIBUTE); |
| } |
| } |
| |
| private static String normalizeCase(String s) { |
| if (NORMALIZE_CASE && s != null) |
| return s.toUpperCase(); |
| return s; |
| } |
| |
| void register(IConfigurationElement element, Object data) { |
| String id = element.getAttribute(ID_ATTRIBUTE); |
| if (id != null) { |
| if (fIdMap == null) |
| fIdMap = new HashMap<>(); |
| fIdMap.put(id, data); |
| } |
| |
| String types = element.getAttribute(EXTENSIONS_ATTRIBUTE); |
| if (types != null) { |
| if (fExtensionMap == null) |
| fExtensionMap = new HashMap<>(); |
| StringTokenizer tokenizer = new StringTokenizer(types, ","); //$NON-NLS-1$ |
| while (tokenizer.hasMoreElements()) { |
| String extension = tokenizer.nextToken().trim(); |
| fExtensionMap.put(normalizeCase(extension), data); |
| } |
| } |
| } |
| |
| void createBinding(IConfigurationElement element, String idAttributeName) { |
| String type = element.getAttribute(CONTENT_TYPE_ID_ATTRIBUTE); |
| String id = element.getAttribute(idAttributeName); |
| if (id == null) |
| logErrorMessage(NLS.bind("Target attribute id '{0}' missing", idAttributeName)); //$NON-NLS-1$ |
| if (type != null && id != null && fIdMap != null) { |
| Object o = fIdMap.get(id); |
| if (o != null) { |
| IContentType ct = Platform.getContentTypeManager().getContentType(type); |
| if (ct != null) { |
| if (fContentTypeBindings == null) |
| fContentTypeBindings = new HashMap<>(); |
| fContentTypeBindings.put(ct, o); |
| } else { |
| logErrorMessage(NLS.bind("Content type id '{0}' not found", type)); //$NON-NLS-1$ |
| } |
| } else { |
| logErrorMessage(NLS.bind("Target '{0}' not found", id)); //$NON-NLS-1$$ |
| } |
| } |
| } |
| |
| private void logErrorMessage(String string) { |
| TeamPlugin.log(IStatus.ERROR, string, null); |
| } |
| |
| Object search(IContentType type) { |
| if (fContentTypeBindings != null) { |
| for (; type != null; type = type.getBaseType()) { |
| Object data = fContentTypeBindings.get(type); |
| if (data != null) |
| return data; |
| } |
| } |
| return null; |
| } |
| |
| Object search(String extension) { |
| if (fExtensionMap != null) |
| return fExtensionMap.get(normalizeCase(extension)); |
| return null; |
| } |
| } |