org.openide.filesystems.MIMEResolver Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.openide.filesystems;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
import org.netbeans.modules.openide.filesystems.declmime.MIMEResolverImpl;
import org.openide.filesystems.annotations.LayerBuilder;
import org.openide.util.NbBundle;
import org.openide.util.Parameters;
import org.openide.util.lookup.ServiceProvider;
/**
* Use the {@link FileUtil#getMIMEType(org.openide.filesystems.FileObject, java.lang.String[])}
* to invoke the mime resolving infrastructure.
* All registered mime resolvers are looked up and asked one by one
* to {@link #findMIMEType(org.openide.filesystems.FileObject) resolve MIME type}
* of passed in {@link FileObject}. Resolving is finished right after
* a resolver is able to resolve the FileObject or if all registered
* resolvers returned null
(not recognized).
*
* Use {@link ExtensionRegistration},
* {@link MIMEResolver.NamespaceRegistration} or {@link MIMEResolver.Registration}
* to register declarative resolvers.
*
* In the rarely case, when declarative resolvers are not sufficient, you can
* register subclass of {@link MIMEResolver} directly by using {@link ServiceProvider}
* annotation.
*
* @author rmatous
*/
public abstract class MIMEResolver {
private String[] resolvableMIMETypes = null;
/** Creates a new MIMEResolver.
* @param mimeTypes an array of MIME types which can be resolved by this resolver.
* It should contain all MIME types which {@link #findMIMEType} can return.
* If something is missing, this resolver can be ignored, when searching for that
* missing MIME type (see {@link FileUtil#getMIMEType(FileObject, String...)}).
* @since 7.13
*/
public MIMEResolver(String... mimeTypes) {
Parameters.notNull("mimeTypes", mimeTypes); //NOI18N
if(mimeTypes.length == 0) {
throw new IllegalArgumentException("The mimeTypes parameter cannot be empty array."); //NOI18N
}
for (String mimeType : mimeTypes) {
if(mimeType == null || mimeType.length() == 0) {
throw new IllegalArgumentException("The item in mimeTypes parameter cannot be null nor empty String."); //NOI18N
}
}
resolvableMIMETypes = mimeTypes;
}
/** Creates a new MIMEResolver.
* @deprecated Use {@link #MIMEResolver(String...)} instead. Declaring MIME
* types which can only be resolved by this resolver helps to speed up IDE.
*/
@Deprecated
public MIMEResolver() {
}
/**
* Resolves FileObject and returns recognized MIME type
* @param fo is FileObject which should be resolved (This FileObject is not
* thread safe. Also this FileObject should not be cached for later use)
* @return recognized MIME type or null if not recognized
*/
public abstract String findMIMEType(FileObject fo);
/** Returns an array of MIME types which can be resolved by this resolver.
* @return a non-empty array of MIME types
*/
String[] getMIMETypes() {
return resolvableMIMETypes;
}
/** factory method for {@link MIMEResolver.Registration} */
static MIMEResolver create(FileObject fo) throws IOException {
return MIMEResolverImpl.create(fo);
}
/** Internal support for implementors of MIME resolver UIs.
*
* @since 7.34
*/
public abstract class UIHelpers {
/** Throws an exception. Allows instantiation only by known subclasses.
* @throws IllegalStateException
*/
protected UIHelpers() {
if (getClass().getName().equals("org.netbeans.core.ui.options.filetypes.FileAssociationsModel")) { // NOI18N
// only core.ui is allowed to use methods of this class.
return;
}
throw new IllegalStateException();
}
/**
* Stores declarative resolver corresponding to specified mapping of MIME type
* and set of extensions. This resolver has the highest priority. Usually
* it resides in userdir/config/Servicer/MIMEResolver.
*
Not intended for use by modules outside the NetBeans Platform.
* @param mimeToExtensions mapping of MIME type to set of extensions like
* {@code {image/jpeg=[jpg, jpeg], image/gif=[]}}
* @since org.openide.filesystems 7.34
*/
protected final void storeUserDefinedResolver(final Map> mimeToExtensions) {
MIMEResolverImpl.storeUserDefinedResolver(mimeToExtensions);
}
/**
* Lists registered MIMEResolver instances in reverse order,
* i.e. first are ones with lower priority (position attribute higher)
* and last are ones with highest prority (position attribute lower).
* Not intended for use by modules outside the NetBeans Platform.
* @return list of all registered MIME resolver definitions in reverse order
* @since org.openide.filesystems 7.34
*/
protected final Collection extends FileObject> getOrderedResolvers() {
return MIMEResolverImpl.getOrderedResolvers();
}
/**
* Checks whether a given resolver is user-defined.
*
Not intended for use by modules outside the NetBeans Platform.
* @param mimeResolverFO resolver definition
* @return true if the specified file is a user-defined MIME resolver, false otherwise
* @since org.openide.filesystems 7.34
*/
protected final boolean isUserDefined(FileObject mimeResolverFO) {
return MIMEResolverImpl.isUserDefined(mimeResolverFO);
}
/**
* Returns mapping of MIME type to set of extensions.
*
Not intended for use by modules outside the NetBeans Platform.
* @param fo MIMEResolver definition
* @return mapping of MIME type to set of extensions like
* {@code {image/jpeg=[jpg, jpeg], image/gif=[]}} (never null but may be empty)
* @since org.openide.filesystems 7.34
*/
protected final Map> getMIMEToExtensions(FileObject fo) {
return MIMEResolverImpl.getMIMEToExtensions(fo);
}
}
/** Often a mime type can be deduced just by looking at a file extension.
* If that is your case, this annotation is for you. It associates
* extension(s) with provided mime type.
*
* If this kind of registration seems to trivial you can try
* {@link MIMEResolver.NamespaceRegistration} or {@link MIMEResolver.Registration}.
* @since 7.58
*/
@Retention(RetentionPolicy.SOURCE)
public @interface ExtensionRegistration {
/** Display name to present this type of objects to the user.
*/
public String displayName();
/** Mime type to be assigned to files with {@link #extension}.
*/
public String mimeType();
/** One or few extensions that should be recognized as given
* {@link #mimeType}.
*/
public String[] extension();
/** In case ordering of mime resolvers is important, one can
* specify it by defining their {@link LayerBuilder#position() position}.
*/
public int position() default Integer.MAX_VALUE;
/**
* Show file filters for this MIME type. Set localized names of file
* filters that should contain files resolved by this resolver.
*
* @see FileChooserBuilder#addDefaultFileFilters()
* @since 8.1
*/
public String[] showInFileChooser() default {};
}
/** Recognize mime type by looking into header of XML files. The
* file will be recognized by following rules:
*
* - If the actual extension is
* among {@link #acceptedExtension()} list, then the recognition
* is over and {@link #mimeType()} is assigned to the file.
*
* - If the extension is not among the list of {@link #checkedExtension()
* extensions to check} (which by default contains
"xml"
), then
* the recognition is over without recognizing any mime type.
*
* -
* If the document contains one of requested {@link #doctypePublicId public ID},
* then the mime type is recognized and the recognition ends.
*
* -
* If the root element is not equal to specified {@link #elementName()},
* then the recognition is over without recognizing the mime type.
*
* -
* If the list of {@link #elementNS()} namespaces is specified and the
* namespace of the root element is not among the list, then the recognition
* is over and no mime type is recognized.
*
* -
* If all the above, passed OK, the {@link #mimeType()} is recognized.
*
*
* If you want to recognize file just by its extension consider
* using {@link MIMEResolver.ExtensionRegistration}.
* @since 7.58
*/
@Retention(RetentionPolicy.SOURCE)
public @interface NamespaceRegistration {
/** Display name to present this type of objects to the user.
*/
public String displayName();
/** Mime type to be assigned to files that match description of this
* annotation.
*/
public String mimeType();
/** In case ordering of mime resolvers is important, one can
* specify it by defining their {@link LayerBuilder#position() position}.
*/
public int position() default Integer.MAX_VALUE;
/** The extension that is automatically accepted. If specified,
* then a file with such extension automatically leads to recognition
* of defined {@link #mimeType()}.
*/
public String[] acceptedExtension() default {};
/** The extension of the file to check. By default only .xml
* files are tested for content. One can change the extension of the file
* by changing the value of this attribute. Assigning an empty array
* to attribute turns the content check on every file
*/
public String[] checkedExtension() default { "xml" };
/** Name of root element. If at least one of the provided element names matches
* the real element name, this condition is satisfied.
* @return one or more element name. May be left empty, if element
* name should not be checked at all.
*/
public String elementName() default "";
/** Accept only elements that have specific namespace. If this
* attribute is specified, then only such {@link #elementName() elements}
* are accepted that have the right namespace.
*/
public String[] elementNS() default {};
/** If this attribute is specified, the system will check whether
* at least one of the specified doctype's public ids, is used in
* the document.
*/
public String[] doctypePublicId() default {};
}
/** Registration that allows effective, declarative registration of
* complex {@link MIMEResolver mime resolvers}.
* For simpler cases rather consider using
* {@link MIMEResolver.NamespaceRegistration} or
* {@link MIMEResolver.ExtensionRegistration}.
*
*
* The resource
* attribute of the annotation should be a relative reference to
* an XML like document describing
* the rules that will be interpreted by the mime recognizing infrastructure.
*
* {@code @}{@link NbBundle.Messages}({
* "NICE_NAME=Nice name!"
* })
* {@code @}MIMEResolver.Registration(
* displayName="#NICE_NAME"
* resource="your-resolver-definition.xml"
* )
* class AnyClassYouHave {
* // ...
* }
*
* The definition is pre-processed during compile time in order to eliminate
* XML parsing during execution.
*
* @since 7.58
*/
@Retention(RetentionPolicy.SOURCE)
public @interface Registration {
/** {@link LayerBuilder#absolutizeResource(javax.lang.model.element.Element, java.lang.String) Relative path}
* to resource XML file describing
* the mime recognition rules.
*/
public String resource();
/** In case ordering of mime resolvers is important, one can
* specify it by defining their {@link LayerBuilder#position() position}.
*/
public int position() default Integer.MAX_VALUE;
/** Display name to present this type of objects to the user.
*/
public String displayName();
/**
* Show file filters for registered MIME types. Set localized names of
* file filters that should accept files resolved by this resolver. Only
* types resolved by file name or extension (not by file content) are
* supported.
*
* @see FileChooserBuilder#addDefaultFileFilters()
* @since 8.1
*/
public String[] showInFileChooser() default {};
}
}