KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.*;
14 import java.util.*;
15 import org.eclipse.core.internal.runtime.RuntimeLog;
16 import org.eclipse.core.runtime.*;
17 import org.eclipse.core.runtime.content.*;
18 import org.eclipse.core.runtime.preferences.IScopeContext;
19 import org.eclipse.osgi.util.NLS;
20 import org.osgi.service.prefs.BackingStoreException;
21 import org.osgi.service.prefs.Preferences;
22
23 /**
24  * @see IContentType
25  */

26 public final class ContentType implements IContentType, IContentTypeInfo {
27
28     /* A placeholder for missing/invalid binary/text describers. */
29     private class InvalidDescriber implements IContentDescriber, ITextContentDescriber {
30         public int describe(InputStream contents, IContentDescription description) {
31             return INVALID;
32         }
33
34         public int describe(Reader contents, IContentDescription description) {
35             return INVALID;
36         }
37
38         public QualifiedName[] getSupportedOptions() {
39             return new QualifiedName[0];
40         }
41     }
42
43     final static byte ASSOCIATED_BY_EXTENSION = 2;
44     final static byte ASSOCIATED_BY_NAME = 1;
45     private static final String JavaDoc DESCRIBER_ELEMENT = "describer"; //$NON-NLS-1$
46
private static ArrayList EMPTY_LIST = new ArrayList(0);
47     private static final Object JavaDoc INHERITED_DESCRIBER = "INHERITED DESCRIBER"; //$NON-NLS-1$
48

49     private static final Object JavaDoc NO_DESCRIBER = "NO DESCRIBER"; //$NON-NLS-1$
50
final static byte NOT_ASSOCIATED = 0;
51     public final static String JavaDoc PREF_DEFAULT_CHARSET = "charset"; //$NON-NLS-1$
52
public final static String JavaDoc PREF_FILE_EXTENSIONS = "file-extensions"; //$NON-NLS-1$
53
public final static String JavaDoc PREF_FILE_NAMES = "file-names"; //$NON-NLS-1$
54
final static byte PRIORITY_HIGH = 1;
55     final static byte PRIORITY_LOW = -1;
56     final static byte PRIORITY_NORMAL = 0;
57     final static int SPEC_PRE_DEFINED = IGNORE_PRE_DEFINED;
58     final static int SPEC_USER_DEFINED = IGNORE_USER_DEFINED;
59     final static byte STATUS_INVALID = 2;
60     final static byte STATUS_UNKNOWN = 0;
61     final static byte STATUS_VALID = 1;
62     private String JavaDoc aliasTargetId;
63     private String JavaDoc baseTypeId;
64     private boolean builtInAssociations = false;
65     private ContentTypeCatalog catalog;
66     private IConfigurationElement contentTypeElement;
67     private DefaultDescription defaultDescription;
68     private Map defaultProperties;
69     private Object JavaDoc describer;
70     // we need a Cloneable list
71
private ArrayList fileSpecs = EMPTY_LIST;
72     String JavaDoc id;
73     private ContentTypeManager manager;
74     private String JavaDoc name;
75     private byte priority;
76     private ContentType target;
77     private String JavaDoc userCharset;
78     private byte validation = STATUS_UNKNOWN;
79     private ContentType baseType;
80     // -1 means unknown
81
private byte depth = -1;
82
83     public static ContentType createContentType(ContentTypeCatalog catalog, String JavaDoc uniqueId, String JavaDoc name, byte priority, String JavaDoc[] fileExtensions, String JavaDoc[] fileNames, String JavaDoc baseTypeId, String JavaDoc aliasTargetId, Map defaultProperties, IConfigurationElement contentTypeElement) {
84         ContentType contentType = new ContentType(catalog.getManager());
85         contentType.catalog = catalog;
86         contentType.defaultDescription = new DefaultDescription(contentType);
87         contentType.id = uniqueId;
88         contentType.name = name;
89         contentType.priority = priority;
90         if ((fileExtensions != null && fileExtensions.length > 0) || (fileNames != null && fileNames.length > 0)) {
91             contentType.builtInAssociations = true;
92             contentType.fileSpecs = new ArrayList(fileExtensions.length + fileNames.length);
93             for (int i = 0; i < fileNames.length; i++)
94                 contentType.internalAddFileSpec(fileNames[i], FILE_NAME_SPEC | SPEC_PRE_DEFINED);
95             for (int i = 0; i < fileExtensions.length; i++)
96                 contentType.internalAddFileSpec(fileExtensions[i], FILE_EXTENSION_SPEC | SPEC_PRE_DEFINED);
97         }
98         contentType.defaultProperties = defaultProperties;
99         contentType.contentTypeElement = contentTypeElement;
100         contentType.baseTypeId = baseTypeId;
101         contentType.aliasTargetId = aliasTargetId;
102         return contentType;
103     }
104
105     static FileSpec createFileSpec(String JavaDoc fileSpec, int type) {
106         return new FileSpec(fileSpec, type);
107     }
108
109     static String JavaDoc getPreferenceKey(int flags) {
110         if ((flags & FILE_EXTENSION_SPEC) != 0)
111             return PREF_FILE_EXTENSIONS;
112         if ((flags & FILE_NAME_SPEC) != 0)
113             return PREF_FILE_NAMES;
114         throw new IllegalArgumentException JavaDoc("Unknown type: " + flags); //$NON-NLS-1$
115
}
116
117     private static String JavaDoc getValidationString(byte validation) {
118         return validation == STATUS_VALID ? "VALID" : (validation == STATUS_INVALID ? "INVALID" : "UNKNOWN"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
119
}
120
121     public static void log(String JavaDoc message, Throwable JavaDoc reason) {
122         // don't log CoreExceptions again
123
IStatus status = new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, reason instanceof CoreException ? null : reason);
124         RuntimeLog.log(status);
125     }
126
127     public ContentType(ContentTypeManager manager) {
128         this.manager = manager;
129     }
130
131     /**
132      * @see IContentType
133      */

134     public void addFileSpec(String JavaDoc fileSpec, int type) throws CoreException {
135         Assert.isLegal(type == FILE_EXTENSION_SPEC || type == FILE_NAME_SPEC, "Unknown type: " + type); //$NON-NLS-1$
136
String JavaDoc[] userSet;
137         synchronized (this) {
138             if (!internalAddFileSpec(fileSpec, type | SPEC_USER_DEFINED))
139                 return;
140             userSet = getFileSpecs(type | IGNORE_PRE_DEFINED);
141         }
142         // persist using preferences
143
Preferences contentTypeNode = manager.getPreferences().node(id);
144         String JavaDoc newValue = Util.toListString(userSet);
145         // we are adding stuff, newValue must be non-null
146
Assert.isNotNull(newValue);
147         setPreference(contentTypeNode, getPreferenceKey(type), newValue);
148         try {
149             contentTypeNode.flush();
150         } catch (BackingStoreException bse) {
151             String JavaDoc message = NLS.bind(ContentMessages.content_errorSavingSettings, id);
152             IStatus status = new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, bse);
153             throw new CoreException(status);
154         }
155         // notify listeners
156
manager.fireContentTypeChangeEvent(this);
157     }
158
159     int describe(IContentDescriber selectedDescriber, ILazySource contents, ContentDescription description) throws IOException {
160         try {
161             return contents.isText() ? ((ITextContentDescriber) selectedDescriber).describe((Reader) contents, description) : selectedDescriber.describe((InputStream) contents, description);
162         } catch (RuntimeException JavaDoc re) {
163             // describer seems to be buggy. just disable it (logging the reason)
164
invalidateDescriber(re);
165         } catch (Error JavaDoc e) {
166             // describer got some serious problem. disable it (logging the reason) and throw the error again
167
invalidateDescriber(e);
168             throw e;
169         } catch (LowLevelIOException llioe) {
170             // throw the actual exception
171
throw llioe.getActualException();
172         } catch (IOException ioe) {
173             // bugs 67841/ 62443 - non-low level IOException should be "ignored"
174
if (ContentTypeManager.DEBUGGING) {
175                 String JavaDoc message = NLS.bind(ContentMessages.content_errorReadingContents, id);
176                 ContentType.log(message, ioe);
177             }
178             // we don't know what the describer would say if the exception didn't occur
179
return IContentDescriber.INDETERMINATE;
180         } finally {
181             contents.rewind();
182         }
183         return IContentDescriber.INVALID;
184     }
185
186     public boolean equals(Object JavaDoc another) {
187         if (another instanceof ContentType)
188             return id.equals(((ContentType) another).id);
189         if (another instanceof ContentTypeHandler)
190             return id.equals(((ContentTypeHandler) another).id);
191         return false;
192     }
193
194     public String JavaDoc getAliasTargetId() {
195         return aliasTargetId;
196     }
197
198     /**
199      * @see IContentType
200      */

201
202     public IContentType getBaseType() {
203         return baseType;
204     }
205
206     String JavaDoc getBaseTypeId() {
207         return baseTypeId;
208     }
209
210     public ContentTypeCatalog getCatalog() {
211         return catalog;
212     }
213
214     public ContentType getContentType() {
215         return this;
216     }
217
218     /**
219      * @see IContentType
220      */

221     public String JavaDoc getDefaultCharset() {
222         return getDefaultProperty(IContentDescription.CHARSET);
223     }
224
225     /**
226      * @see IContentType
227      */

228     public IContentDescription getDefaultDescription() {
229         return defaultDescription;
230     }
231
232     /**
233      * Returns the default value for the given property in this content type, or <code>null</code>.
234      */

235     public String JavaDoc getDefaultProperty(QualifiedName key) {
236         String JavaDoc propertyValue = internalGetDefaultProperty(key);
237         if ("".equals(propertyValue)) //$NON-NLS-1$
238
return null;
239         return propertyValue;
240     }
241
242     byte getDepth() {
243         byte tmpDepth = depth;
244         if (tmpDepth >= 0)
245             return tmpDepth;
246         // depth was never computed - do it now
247
if (baseType == null)
248             return depth = 0;
249         return depth = (byte) (baseType == null ? 0 : (1 + baseType.getDepth()));
250     }
251
252     /**
253      * Public for tests only, should not be called by anyone else.
254      */

255     public IContentDescriber getDescriber() {
256         try {
257             // thread safety
258
Object JavaDoc tmpDescriber = describer;
259             if (tmpDescriber != null) {
260                 if (INHERITED_DESCRIBER == tmpDescriber)
261                     return baseType.getDescriber();
262                 return (NO_DESCRIBER == tmpDescriber) ? null : (IContentDescriber) tmpDescriber;
263             }
264             final String JavaDoc describerValue = contentTypeElement.getAttributeAsIs(DESCRIBER_ELEMENT);
265             if (describerValue != null || contentTypeElement.getChildren(DESCRIBER_ELEMENT).length > 0)
266                 try {
267                     if ("".equals(describerValue)) { //$NON-NLS-1$
268
describer = NO_DESCRIBER;
269                         return null;
270                     }
271                     describer = tmpDescriber = contentTypeElement.createExecutableExtension(DESCRIBER_ELEMENT);
272                     return (IContentDescriber) tmpDescriber;
273                 } catch (CoreException ce) {
274                     // the content type definition was invalid. Ensure we don't
275
// try again, and this content type does not accept any
276
// contents
277
return invalidateDescriber(ce);
278                 }
279         } catch (InvalidRegistryObjectException e) {
280             /*
281              * This should only happen if an API call is made after the registry has changed and before
282              * the corresponding registry change event has been broadcast.
283              */

284             // the configuration element is stale - need to rebuild the catalog
285
manager.invalidate();
286             // bad timing - next time the client asks for a describer, s/he will have better luck
287
return null;
288         }
289         if (baseType == null) {
290             describer = NO_DESCRIBER;
291             return null;
292         }
293         // remember so we don't have to come all the way down here next time
294
describer = INHERITED_DESCRIBER;
295         return baseType.getDescriber();
296     }
297
298     /**
299      * @see IContentType
300      */

301     public IContentDescription getDescriptionFor(InputStream contents, QualifiedName[] options) throws IOException {
302         return internalGetDescriptionFor(ContentTypeManager.readBuffer(contents), options);
303     }
304
305     /**
306      * @see IContentType
307      */

308     public IContentDescription getDescriptionFor(Reader contents, QualifiedName[] options) throws IOException {
309         return internalGetDescriptionFor(ContentTypeManager.readBuffer(contents), options);
310     }
311
312     /**
313      * @see IContentType
314      */

315     public String JavaDoc[] getFileSpecs(int typeMask) {
316         if (fileSpecs.isEmpty())
317             return new String JavaDoc[0];
318         // invert the last two bits so it is easier to compare
319
typeMask ^= (IGNORE_PRE_DEFINED | IGNORE_USER_DEFINED);
320         List result = new ArrayList(fileSpecs.size());
321         for (Iterator i = fileSpecs.iterator(); i.hasNext();) {
322             FileSpec spec = (FileSpec) i.next();
323             if ((spec.getType() & typeMask) == spec.getType())
324                 result.add(spec.getText());
325         }
326         return (String JavaDoc[]) result.toArray(new String JavaDoc[result.size()]);
327     }
328
329     /**
330      * @see IContentType
331      */

332     public String JavaDoc getId() {
333         return id;
334     }
335
336     /**
337      * @see IContentType
338      */

339     public String JavaDoc getName() {
340         return name;
341     }
342
343     byte getPriority() {
344         return priority;
345     }
346
347     public IContentTypeSettings getSettings(IScopeContext context) {
348         if (context == null || context.equals(manager.getContext()))
349             return this;
350         return new ContentTypeSettings(this, context);
351     }
352
353     /*
354      * Returns the alias target, if one is found, or this object otherwise.
355      */

356     ContentType getAliasTarget(boolean self) {
357         return (self && target == null) ? this : target;
358     }
359
360     byte getValidation() {
361         return validation;
362     }
363
364     boolean hasBuiltInAssociations() {
365         return builtInAssociations;
366     }
367
368     boolean hasFileSpec(IScopeContext context, String JavaDoc text, int typeMask) {
369         if (context.equals(manager.getContext()) || (typeMask & IGNORE_USER_DEFINED) != 0)
370             return hasFileSpec(text, typeMask, false);
371         String JavaDoc[] fileSpecs = ContentTypeSettings.getFileSpecs(context, id, typeMask);
372         for (int i = 0; i < fileSpecs.length; i++)
373             if (text.equalsIgnoreCase(fileSpecs[i]))
374                 return true;
375         // no user defined association... try built-in
376
return hasFileSpec(text, typeMask | IGNORE_PRE_DEFINED, false);
377     }
378
379     /**
380      * Returns whether this content type has the given file spec.
381      *
382      * @param text the file spec string
383      * @param typeMask FILE_NAME_SPEC or FILE_EXTENSION_SPEC
384      * @param strict
385      * @return true if this file spec has already been added, false otherwise
386      */

387     boolean hasFileSpec(String JavaDoc text, int typeMask, boolean strict) {
388         if (fileSpecs.isEmpty())
389             return false;
390         for (Iterator i = fileSpecs.iterator(); i.hasNext();) {
391             FileSpec spec = (FileSpec) i.next();
392             if (spec.equals(text, typeMask, strict))
393                 return true;
394         }
395         return false;
396     }
397
398     public int hashCode() {
399         return id.hashCode();
400     }
401
402     /**
403      * Adds a user-defined or pre-defined file spec.
404      */

405     boolean internalAddFileSpec(String JavaDoc fileSpec, int typeMask) {
406         if (hasFileSpec(fileSpec, typeMask, false))
407             return false;
408         FileSpec newFileSpec = createFileSpec(fileSpec, typeMask);
409         if ((typeMask & ContentType.SPEC_USER_DEFINED) == 0) {
410             // plug-in defined - all that is left to be done is to add it to the list
411
if (fileSpecs.isEmpty())
412                 fileSpecs = new ArrayList(3);
413             fileSpecs.add(newFileSpec);
414             return true;
415         }
416         // update file specs atomically so threads traversing the list of file specs don't have to synchronize
417
ArrayList tmpFileSpecs = (ArrayList) fileSpecs.clone();
418         tmpFileSpecs.add(newFileSpec);
419         catalog.associate(this, newFileSpec.getText(), newFileSpec.getType());
420         // set the new file specs atomically
421
fileSpecs = tmpFileSpecs;
422         return true;
423     }
424
425     /**
426      * Returns the default value for a property, recursively if necessary.
427      */

428     String JavaDoc internalGetDefaultProperty(QualifiedName key) {
429         // a special case for charset - users can override
430
if (userCharset != null && key.equals(IContentDescription.CHARSET))
431             return userCharset;
432         String JavaDoc defaultValue = basicGetDefaultProperty(key);
433         if (defaultValue != null)
434             return defaultValue;
435         // not defined here, try base type
436
return baseType == null ? null : baseType.internalGetDefaultProperty(key);
437     }
438
439     /**
440      * Returns the value of a built-in property defined for this content type.
441      */

442     String JavaDoc basicGetDefaultProperty(QualifiedName key) {
443         return defaultProperties == null ? null : (String JavaDoc) defaultProperties.get(key);
444     }
445
446     BasicDescription internalGetDescriptionFor(ILazySource buffer, QualifiedName[] options) throws IOException {
447         if (buffer == null)
448             return defaultDescription;
449         // use temporary local var to avoid sync'ing
450
IContentDescriber tmpDescriber = this.getDescriber();
451         // no describer - return default description
452
if (tmpDescriber == null)
453             return defaultDescription;
454         if (buffer.isText() && !(tmpDescriber instanceof ITextContentDescriber))
455             // it is an error to provide a Reader to a non-text content type
456
throw new UnsupportedOperationException JavaDoc();
457         ContentDescription description = new ContentDescription(options, this);
458         if (describe(tmpDescriber, buffer, description) == IContentDescriber.INVALID)
459             // the contents were actually invalid for the content type
460
return null;
461         // the describer didn't add any details, return default description
462
if (!description.isSet())
463             return defaultDescription;
464         // description cannot be changed afterwards
465
description.markImmutable();
466         return description;
467     }
468
469     byte internalIsAssociatedWith(String JavaDoc fileName, IScopeContext context) {
470         if (hasFileSpec(context, fileName, FILE_NAME_SPEC))
471             return ASSOCIATED_BY_NAME;
472         String JavaDoc fileExtension = ContentTypeManager.getFileExtension(fileName);
473         if (hasFileSpec(context, fileExtension, FILE_EXTENSION_SPEC))
474             return ASSOCIATED_BY_EXTENSION;
475         // if does not have built-in file specs, delegate to parent (if any)
476
if (!hasBuiltInAssociations() && baseType != null)
477             return baseType.internalIsAssociatedWith(fileName, context);
478         return NOT_ASSOCIATED;
479     }
480
481     boolean internalRemoveFileSpec(String JavaDoc fileSpec, int typeMask) {
482         if (fileSpecs.isEmpty())
483             return false;
484         // we modify the list of file specs atomically so we don't interfere with threads doing traversals
485
ArrayList tmpFileSpecs = (ArrayList) fileSpecs.clone();
486         for (Iterator i = tmpFileSpecs.iterator(); i.hasNext();) {
487             FileSpec spec = (FileSpec) i.next();
488             if ((spec.getType() == typeMask) && fileSpec.equals(spec.getText())) {
489                 i.remove();
490                 catalog.dissociate(this, spec.getText(), spec.getType());
491                 // update the list of file specs
492
fileSpecs = tmpFileSpecs;
493                 return true;
494             }
495         }
496         return false;
497     }
498
499     private IContentDescriber invalidateDescriber(Throwable JavaDoc reason) {
500         String JavaDoc message = NLS.bind(ContentMessages.content_invalidContentDescriber, id);
501         log(message, reason);
502         return (IContentDescriber) (describer = new InvalidDescriber());
503     }
504
505     boolean isAlias() {
506         return target != null;
507     }
508
509     /**
510      * @see IContentType
511      */

512     public boolean isAssociatedWith(String JavaDoc fileName) {
513         return isAssociatedWith(fileName, manager.getContext());
514     }
515
516     /**
517      * @see IContentType
518      */

519     public boolean isAssociatedWith(String JavaDoc fileName, IScopeContext context) {
520         return internalIsAssociatedWith(fileName, context) != NOT_ASSOCIATED;
521     }
522
523     /**
524      * @see IContentType
525      */

526     public boolean isKindOf(IContentType another) {
527         if (another == null)
528             return false;
529         if (this == another)
530             return true;
531         return baseType != null && baseType.isKindOf(another);
532     }
533
534     boolean isValid() {
535         return validation == STATUS_VALID;
536     }
537
538     void processPreferences(Preferences contentTypeNode) {
539         // user set default charset
540
this.userCharset = contentTypeNode.get(PREF_DEFAULT_CHARSET, null);
541         // user set file names
542
String JavaDoc userSetFileNames = contentTypeNode.get(PREF_FILE_NAMES, null);
543         String JavaDoc[] fileNames = Util.parseItems(userSetFileNames);
544         for (int i = 0; i < fileNames.length; i++)
545             internalAddFileSpec(fileNames[i], FILE_NAME_SPEC | SPEC_USER_DEFINED);
546         // user set file extensions
547
String JavaDoc userSetFileExtensions = contentTypeNode.get(PREF_FILE_EXTENSIONS, null);
548         String JavaDoc[] fileExtensions = Util.parseItems(userSetFileExtensions);
549         for (int i = 0; i < fileExtensions.length; i++)
550             internalAddFileSpec(fileExtensions[i], FILE_EXTENSION_SPEC | SPEC_USER_DEFINED);
551     }
552
553     /**
554      * @see IContentType
555      */

556     public void removeFileSpec(String JavaDoc fileSpec, int type) throws CoreException {
557         Assert.isLegal(type == FILE_EXTENSION_SPEC || type == FILE_NAME_SPEC, "Unknown type: " + type); //$NON-NLS-1$
558
synchronized (this) {
559             if (!internalRemoveFileSpec(fileSpec, type | SPEC_USER_DEFINED))
560                 return;
561         }
562         // persist the change
563
Preferences contentTypeNode = manager.getPreferences().node(id);
564         final String JavaDoc[] userSet = getFileSpecs(type | IGNORE_PRE_DEFINED);
565         String JavaDoc preferenceKey = getPreferenceKey(type);
566         String JavaDoc newValue = Util.toListString(userSet);
567         setPreference(contentTypeNode, preferenceKey, newValue);
568         try {
569             contentTypeNode.flush();
570         } catch (BackingStoreException bse) {
571             String JavaDoc message = NLS.bind(ContentMessages.content_errorSavingSettings, id);
572             IStatus status = new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, bse);
573             throw new CoreException(status);
574         }
575         // notify listeners
576
manager.fireContentTypeChangeEvent(this);
577     }
578
579     void setAliasTarget(ContentType newTarget) {
580         target = newTarget;
581     }
582
583     /**
584      * @see IContentType
585      */

586     public void setDefaultCharset(String JavaDoc newCharset) throws CoreException {
587         synchronized (this) {
588             // don't do anything if there is no actual change
589
if (userCharset == null) {
590                 if (newCharset == null)
591                     return;
592             } else if (userCharset.equals(newCharset))
593                 return;
594             // apply change in memory
595
userCharset = newCharset;
596         }
597         // persist the change
598
Preferences contentTypeNode = manager.getPreferences().node(id);
599         setPreference(contentTypeNode, PREF_DEFAULT_CHARSET, userCharset);
600         try {
601             contentTypeNode.flush();
602         } catch (BackingStoreException bse) {
603             String JavaDoc message = NLS.bind(ContentMessages.content_errorSavingSettings, id);
604             IStatus status = new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, bse);
605             throw new CoreException(status);
606         }
607         // notify listeners
608
manager.fireContentTypeChangeEvent(this);
609     }
610
611     static void setPreference(Preferences node, String JavaDoc key, String JavaDoc value) {
612         if (value == null)
613             node.remove(key);
614         else
615             node.put(key, value);
616     }
617
618     void setValidation(byte validation) {
619         this.validation = validation;
620         if (ContentTypeManager.DEBUGGING)
621             ContentMessages.message("Validating " + this + ": " + getValidationString(validation)); //$NON-NLS-1$ //$NON-NLS-2$
622
}
623
624     public String JavaDoc toString() {
625         return id;
626     }
627
628     void setBaseType(ContentType baseType) {
629         this.baseType = baseType;
630     }
631
632 }
633
Popular Tags