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;
public class ContentTypeBuilder {
public static final String PT_CONTENTTYPES = "contentTypes";
private ContentTypeCatalog catalog;
private static String getUniqueId(String namespace, String baseTypeId) {
if (baseTypeId == null)
return null;
int separatorPosition = baseTypeId.lastIndexOf('.');
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('.');
if (separatorPosition == -1)
return new QualifiedName(namespace, value);
if (separatorPosition == 0 || separatorPosition == value.length() - 1)
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"))
return ContentType.PRIORITY_HIGH;
if (priority.equals("low"))
return ContentType.PRIORITY_LOW;
if (!priority.equals("normal"))
return ContentType.PRIORITY_NORMAL;
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"));
for (String fileName : fileNames)
target.internalAddFileSpec(fileName, IContentType.FILE_NAME_SPEC | ContentType.SPEC_PRE_DEFINED);
String[] fileExtensions = Util.parseItems(fileAssociationElement.getAttribute("file-extensions"));
for (String fileExtension : fileExtensions)
target.internalAddFileSpec(fileExtension, IContentType.FILE_EXTENSION_SPEC | ContentType.SPEC_PRE_DEFINED);
String[] filePatterns = Util.parseItems(fileAssociationElement.getAttribute("file-patterns"));
for (String filePattern : filePatterns)
target.internalAddFileSpec(filePattern, IContentType.FILE_PATTERN_SPEC | ContentType.SPEC_PRE_DEFINED);
}
public void buildCatalog(IScopeContext context) {
IConfigurationElement[] allContentTypeCEs = getConfigurationElements();
for (IConfigurationElement allContentTypeCE : allContentTypeCEs)
if (allContentTypeCE.getName().equals("content-type"))
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"))
registerFileAssociation(allContentTypeCE);
applyPreferences();
}
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);
return false;
}
});
} catch (BackingStoreException bse) {
ContentType.log(ContentMessages.content_errorLoadingSettings, bse);
}
}
private ContentType createContentType(IConfigurationElement contentTypeCE) throws CoreException {
String namespace = contentTypeCE.getContributor().getName();
String simpleId = contentTypeCE.getAttribute("id");
String name = contentTypeCE.getAttribute("name");
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"));
String[] fileNames = Util.parseItems(contentTypeCE.getAttribute("file-names"));
String[] fileExtensions = Util.parseItems(contentTypeCE.getAttribute("file-extensions"));
String[] filePatterns = Util.parseItems(contentTypeCE.getAttribute("file-patterns"));
String baseTypeId = getUniqueId(namespace, contentTypeCE.getAttribute("base-type"));
String aliasTargetTypeId = getUniqueId(namespace, contentTypeCE.getAttribute("alias-for"));
IConfigurationElement[] propertyCEs = null;
Map<QualifiedName, String> defaultProperties = null;
if ((propertyCEs = contentTypeCE.getChildren("property")).length > 0) {
defaultProperties = new HashMap<>();
for (IConfigurationElement propertyCE : propertyCEs) {
String defaultValue = propertyCE.getAttribute("default");
if (defaultValue == null)
defaultValue = "";
String propertyKey = propertyCE.getAttribute("name");
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");
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);
}
private final static IConfigurationElement[] emptyConfArray = new IConfigurationElement[0];
protected IConfigurationElement[] getConfigurationElements() {
IExtensionRegistry registry = RegistryFactory.getRegistry();
if (registry == null)
return emptyConfArray;
IConfigurationElement[] oldConfigElements = emptyConfArray;
IConfigurationElement[] newConfigElements = emptyConfArray;
IExtensionPoint oldPoint = registry.getExtensionPoint(IContentConstants.RUNTIME_NAME, PT_CONTENTTYPES);
if (oldPoint != null)
oldConfigElements = oldPoint.getConfigurationElements();
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) {
RuntimeLog.log(e.getStatus());
}
}
private void registerFileAssociation(IConfigurationElement fileAssociationElement) {
String contentTypeId = getUniqueId(fileAssociationElement.getContributor().getName(), fileAssociationElement.getAttribute("content-type"));
ContentType target = catalog.internalGetContentType(contentTypeId);
if (target == null)
return;
addFileAssociation(fileAssociationElement, target);
}
}