blob: 9b3db27c348170a26cd11f7f31f352c33149922a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2005 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.core.internal.content;
import java.util.*;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.internal.runtime.Messages;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.osgi.util.NLS;
/**
* 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.getAttributeAsIs("file-names")); //$NON-NLS-1$
for (int i = 0; i < fileNames.length; i++)
target.internalAddFileSpec(catalog, fileNames[i], IContentType.FILE_NAME_SPEC | ContentType.SPEC_PRE_DEFINED);
String[] fileExtensions = Util.parseItems(fileAssociationElement.getAttributeAsIs("file-extensions")); //$NON-NLS-1$
for (int i = 0; i < fileExtensions.length; i++)
target.internalAddFileSpec(catalog, fileExtensions[i], IContentType.FILE_EXTENSION_SPEC | ContentType.SPEC_PRE_DEFINED);
}
/**
* Builds all content types found in the extension registry.
*/
public void buildCatalog() {
IConfigurationElement[] allContentTypeCEs = getConfigurationElements();
for (int i = 0; i < allContentTypeCEs.length; i++) {
if (allContentTypeCEs[i].getName().equals("content-type")) //$NON-NLS-1$
registerContentType(allContentTypeCEs[i]);
}
for (int i = 0; i < allContentTypeCEs.length; i++) {
if (allContentTypeCEs[i].getName().equals("file-association")) //$NON-NLS-1$
registerFileAssociation(allContentTypeCEs[i]);
}
}
private ContentType createContentType(IConfigurationElement contentTypeCE) {
//TODO: need to ensure the config. element is valid
String simpleId = contentTypeCE.getAttributeAsIs("id"); //$NON-NLS-1$
byte priority = parsePriority(contentTypeCE.getAttributeAsIs("priority")); //$NON-NLS-1$);
String namespace = contentTypeCE.getDeclaringExtension().getNamespace();
String name = contentTypeCE.getAttribute("name"); //$NON-NLS-1$
String[] fileNames = Util.parseItems(contentTypeCE.getAttributeAsIs("file-names")); //$NON-NLS-1$
String[] fileExtensions = Util.parseItems(contentTypeCE.getAttributeAsIs("file-extensions")); //$NON-NLS-1$
String baseTypeId = getUniqueId(namespace, contentTypeCE.getAttributeAsIs("base-type")); //$NON-NLS-1$
String aliasTargetTypeId = getUniqueId(namespace, contentTypeCE.getAttributeAsIs("alias-for")); //$NON-NLS-1$
IConfigurationElement[] propertyCEs = null;
Map defaultProperties = null;
if ((propertyCEs = contentTypeCE.getChildren("property")).length > 0) { //$NON-NLS-1$
defaultProperties = new HashMap();
for (int i = 0; i < propertyCEs.length; i++) {
String defaultValue = propertyCEs[i].getAttributeAsIs("default"); //$NON-NLS-1$
if (defaultValue == null)
// empty string means: default value is null
defaultValue = ""; //$NON-NLS-1$
String propertyKey = propertyCEs[i].getAttributeAsIs("name"); //$NON-NLS-1$
QualifiedName qualifiedKey = parseQualifiedName(namespace, propertyKey);
if (qualifiedKey == null) {
if (ContentTypeManager.DEBUGGING) {
String message = NLS.bind(Messages.content_invalidProperty, propertyKey, getUniqueId(namespace, simpleId));
ContentType.log(message, null);
}
continue;
}
defaultProperties.put(qualifiedKey, defaultValue);
}
}
String defaultCharset = contentTypeCE.getAttributeAsIs("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, namespace, simpleId, name, priority, fileExtensions, fileNames, baseTypeId, aliasTargetTypeId, defaultProperties, contentTypeCE);
}
protected IConfigurationElement[] getConfigurationElements() {
IExtensionRegistry registry = InternalPlatform.getDefault().getRegistry();
IExtensionPoint contentTypesXP = registry.getExtensionPoint(Platform.PI_RUNTIME, PT_CONTENTTYPES);
IConfigurationElement[] allContentTypeCEs = contentTypesXP.getConfigurationElements();
return allContentTypeCEs;
}
/* Checks whether the content type has all required pieces. */
private boolean isComplete(ContentType contentType) {
String message = null;
if (contentType.getSimpleId() == null)
message = NLS.bind(Messages.content_missingIdentifier, contentType.getId());
else if (contentType.getName() == null)
message = NLS.bind(Messages.content_missingName, contentType.getId());
if (message == null)
return true;
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, 0, message, null);
InternalPlatform.getDefault().log(status);
return false;
}
private void registerContentType(IConfigurationElement contentTypeCE) {
//TODO: need to ensure the config. element is valid
ContentType contentType = createContentType(contentTypeCE);
if (!isComplete(contentType))
return;
catalog.addContentType(contentType);
}
/* 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.getDeclaringExtension().getNamespace(), fileAssociationElement.getAttribute("content-type")); //$NON-NLS-1$
ContentType target = catalog.internalGetContentType(contentTypeId);
if (target == null)
return;
addFileAssociation(fileAssociationElement, target);
}
}