KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > content > ContentTypeBuilder


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.content;
12
13 import java.util.*;
14 import org.eclipse.core.internal.runtime.RuntimeLog;
15 import org.eclipse.core.runtime.*;
16 import org.eclipse.core.runtime.content.IContentDescription;
17 import org.eclipse.core.runtime.content.IContentType;
18 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
19 import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor;
20 import org.eclipse.osgi.util.NLS;
21 import org.osgi.service.prefs.BackingStoreException;
22
23 /**
24  * This class is a sidekick for ContentTypeManager that provides mechanisms for
25  * creating content types from the extension registry (which ContentTypeManager
26  * is oblivious to).
27  */

28 public class ContentTypeBuilder {
29     public static final String JavaDoc PT_CONTENTTYPES = "contentTypes"; //$NON-NLS-1$
30
private ContentTypeCatalog catalog;
31
32     private static String JavaDoc getUniqueId(String JavaDoc namespace, String JavaDoc baseTypeId) {
33         if (baseTypeId == null)
34             return null;
35         int separatorPosition = baseTypeId.lastIndexOf('.');
36         // base type is defined in the same namespace
37
if (separatorPosition == -1)
38             baseTypeId = namespace + '.' + baseTypeId;
39         return baseTypeId;
40     }
41
42     private static QualifiedName parseQualifiedName(String JavaDoc namespace, String JavaDoc value) {
43         if (value == null)
44             return null;
45         int separatorPosition = value.lastIndexOf('.');
46         // base type is defined in the same namespace
47
if (separatorPosition == -1)
48             return new QualifiedName(namespace, value);
49         if (separatorPosition == 0 || separatorPosition == value.length() - 1)
50             // invalid value specified
51
return null;
52         namespace = value.substring(0, separatorPosition);
53         String JavaDoc simpleValue = value.substring(separatorPosition + 1);
54         return new QualifiedName(namespace, simpleValue);
55     }
56
57     private static byte parsePriority(String JavaDoc priority) {
58         if (priority == null)
59             return ContentType.PRIORITY_NORMAL;
60         if (priority.equals("high")) //$NON-NLS-1$
61
return ContentType.PRIORITY_HIGH;
62         if (priority.equals("low")) //$NON-NLS-1$
63
return ContentType.PRIORITY_LOW;
64         if (!priority.equals("normal")) //$NON-NLS-1$
65
return ContentType.PRIORITY_NORMAL;
66         //TODO: should log - INVALID PRIORITY
67
return ContentType.PRIORITY_NORMAL;
68     }
69
70     protected ContentTypeBuilder(ContentTypeCatalog catalog) {
71         this.catalog = catalog;
72     }
73
74     private void addFileAssociation(IConfigurationElement fileAssociationElement, ContentType target) {
75         String JavaDoc[] fileNames = Util.parseItems(fileAssociationElement.getAttributeAsIs("file-names")); //$NON-NLS-1$
76
for (int i = 0; i < fileNames.length; i++)
77             target.internalAddFileSpec(fileNames[i], IContentType.FILE_NAME_SPEC | ContentType.SPEC_PRE_DEFINED);
78         String JavaDoc[] fileExtensions = Util.parseItems(fileAssociationElement.getAttributeAsIs("file-extensions")); //$NON-NLS-1$
79
for (int i = 0; i < fileExtensions.length; i++)
80             target.internalAddFileSpec(fileExtensions[i], IContentType.FILE_EXTENSION_SPEC | ContentType.SPEC_PRE_DEFINED);
81     }
82
83     /**
84      * Builds all content types found in the extension registry.
85      */

86     public void buildCatalog() {
87         IConfigurationElement[] allContentTypeCEs = getConfigurationElements();
88         for (int i = 0; i < allContentTypeCEs.length; i++)
89             if (allContentTypeCEs[i].getName().equals("content-type")) //$NON-NLS-1$
90
registerContentType(allContentTypeCEs[i]);
91         for (int i = 0; i < allContentTypeCEs.length; i++)
92             if (allContentTypeCEs[i].getName().equals("file-association")) //$NON-NLS-1$
93
registerFileAssociation(allContentTypeCEs[i]);
94         applyPreferences();
95     }
96
97     /**
98      * Applies any existing preferences to content types as a batch operation.
99      */

100     private void applyPreferences() {
101         try {
102             final ContentTypeCatalog localCatalog = catalog;
103             final IEclipsePreferences root = localCatalog.getManager().getPreferences();
104             root.accept(new IPreferenceNodeVisitor() {
105                 public boolean visit(IEclipsePreferences node) {
106                     if (node == root)
107                         return true;
108                     ContentType contentType = localCatalog.internalGetContentType(node.name());
109                     if (contentType != null)
110                         contentType.processPreferences(node);
111                     // content type nodes don't have any children anyway
112
return false;
113                 }
114             });
115         } catch (BackingStoreException bse) {
116             ContentType.log(ContentMessages.content_errorLoadingSettings, bse);
117         }
118     }
119
120     /**
121      * @throws CoreException if mandatory attributes are missing in the markup
122      */

123     private ContentType createContentType(IConfigurationElement contentTypeCE) throws CoreException {
124         String JavaDoc namespace = contentTypeCE.getContributor().getName();
125         String JavaDoc simpleId = contentTypeCE.getAttributeAsIs("id"); //$NON-NLS-1$
126
String JavaDoc name = contentTypeCE.getAttribute("name"); //$NON-NLS-1$
127

128         if (simpleId == null)
129             missingMandatoryAttribute(ContentMessages.content_missingIdentifier, namespace);
130         String JavaDoc uniqueId;
131         if (simpleId.lastIndexOf('.') == -1)
132             uniqueId = namespace + '.' + simpleId;
133         else
134             uniqueId = simpleId;
135         if (name == null)
136             missingMandatoryAttribute(ContentMessages.content_missingName, uniqueId);
137
138         byte priority = parsePriority(contentTypeCE.getAttributeAsIs("priority")); //$NON-NLS-1$);
139
String JavaDoc[] fileNames = Util.parseItems(contentTypeCE.getAttributeAsIs("file-names")); //$NON-NLS-1$
140
String JavaDoc[] fileExtensions = Util.parseItems(contentTypeCE.getAttributeAsIs("file-extensions")); //$NON-NLS-1$
141
String JavaDoc baseTypeId = getUniqueId(namespace, contentTypeCE.getAttributeAsIs("base-type")); //$NON-NLS-1$
142
String JavaDoc aliasTargetTypeId = getUniqueId(namespace, contentTypeCE.getAttributeAsIs("alias-for")); //$NON-NLS-1$
143
IConfigurationElement[] propertyCEs = null;
144         Map defaultProperties = null;
145         if ((propertyCEs = contentTypeCE.getChildren("property")).length > 0) { //$NON-NLS-1$
146
defaultProperties = new HashMap();
147             for (int i = 0; i < propertyCEs.length; i++) {
148                 String JavaDoc defaultValue = propertyCEs[i].getAttributeAsIs("default"); //$NON-NLS-1$
149
if (defaultValue == null)
150                     // empty string means: default value is null
151
defaultValue = ""; //$NON-NLS-1$
152
String JavaDoc propertyKey = propertyCEs[i].getAttributeAsIs("name"); //$NON-NLS-1$
153
QualifiedName qualifiedKey = parseQualifiedName(namespace, propertyKey);
154                 if (qualifiedKey == null) {
155                     if (ContentTypeManager.DEBUGGING) {
156                         String JavaDoc message = NLS.bind(ContentMessages.content_invalidProperty, propertyKey, getUniqueId(namespace, simpleId));
157                         ContentType.log(message, null);
158                     }
159                     continue;
160                 }
161                 defaultProperties.put(qualifiedKey, defaultValue);
162             }
163         }
164         String JavaDoc defaultCharset = contentTypeCE.getAttributeAsIs("default-charset"); //$NON-NLS-1$
165
if (defaultCharset != null)
166             if (defaultProperties == null)
167                 defaultProperties = Collections.singletonMap(IContentDescription.CHARSET, defaultCharset);
168             else if (!defaultProperties.containsKey(IContentDescription.CHARSET))
169                 defaultProperties.put(IContentDescription.CHARSET, defaultCharset);
170         return ContentType.createContentType(catalog, uniqueId, name, priority, fileExtensions, fileNames, baseTypeId, aliasTargetTypeId, defaultProperties, contentTypeCE);
171     }
172
173     // Store this around for performance
174
private final static IConfigurationElement[] emptyConfArray = new IConfigurationElement[0];
175
176     /**
177      * Gets confuguration elements for both "backward compatible" extension point
178      * org.eclipse.core.runtime.contentTypes
179      * and "new" extension point controlled by this plugin:
180      * org.eclipse.core.contenttype.contentTypes
181      */

182     protected IConfigurationElement[] getConfigurationElements() {
183         IExtensionRegistry registry = RegistryFactory.getRegistry();
184         if (registry == null)
185             return emptyConfArray;
186         IConfigurationElement[] oldConfigElements = emptyConfArray;
187         IConfigurationElement[] newConfigElements = emptyConfArray;
188         // "old" extenstion point
189
IExtensionPoint oldPoint = registry.getExtensionPoint(IContentConstants.RUNTIME_NAME, PT_CONTENTTYPES);
190         if (oldPoint != null)
191             oldConfigElements = oldPoint.getConfigurationElements();
192         // "new" extension point
193
IExtensionPoint newPoint = registry.getExtensionPoint(IContentConstants.CONTENT_NAME, PT_CONTENTTYPES);
194         if (newPoint != null)
195             newConfigElements = newPoint.getConfigurationElements();
196
197         IConfigurationElement[] allContentTypeCEs = new IConfigurationElement[oldConfigElements.length + newConfigElements.length];
198         System.arraycopy(oldConfigElements, 0, allContentTypeCEs, 0, oldConfigElements.length);
199         System.arraycopy(newConfigElements, 0, allContentTypeCEs, oldConfigElements.length, newConfigElements.length);
200
201         return allContentTypeCEs;
202     }
203
204     private void missingMandatoryAttribute(String JavaDoc messageKey, String JavaDoc argument) throws CoreException {
205         String JavaDoc message = NLS.bind(messageKey, argument);
206         throw new CoreException(new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, null));
207     }
208
209     private void registerContentType(IConfigurationElement contentTypeCE) {
210         try {
211             ContentType contentType = createContentType(contentTypeCE);
212             catalog.addContentType(contentType);
213         } catch (CoreException e) {
214             // failed validation
215
RuntimeLog.log(e.getStatus());
216         }
217     }
218
219     /* Adds extra file associations to existing content types. If the content
220      * type has not been added, the file association is ignored.
221      */

222     private void registerFileAssociation(IConfigurationElement fileAssociationElement) {
223         //TODO: need to ensure the config. element is valid
224
String JavaDoc contentTypeId = getUniqueId(fileAssociationElement.getContributor().getName(), fileAssociationElement.getAttribute("content-type")); //$NON-NLS-1$
225
ContentType target = catalog.internalGetContentType(contentTypeId);
226         if (target == null)
227             return;
228         addFileAssociation(fileAssociationElement, target);
229     }
230 }
231
Popular Tags