001    /*
002     * Copyright 2007 - 2007 JEuclid, http://jeuclid.sf.net
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    /* $Id: ConverterRegistry.java,v 5a7becda9147 2009/10/23 10:57:54 max $ */
018    
019    package net.sourceforge.jeuclid.converter;
020    
021    import java.util.HashMap;
022    import java.util.HashSet;
023    import java.util.Iterator;
024    import java.util.Locale;
025    import java.util.Map;
026    import java.util.Set;
027    
028    import org.apache.xmlgraphics.util.Service;
029    
030    /**
031     * A registry for image converters.
032     * 
033     * @version $Revision: 5a7becda9147 $
034     */
035    public final class ConverterRegistry {
036    
037        private static final class SingletonHolder {
038            private static final ConverterRegistry INSTANCE = new ConverterRegistry();
039    
040            private SingletonHolder() {
041            }
042        }
043    
044        private final Map<String, ConverterPlugin> mimetype2converter = new HashMap<String, ConverterPlugin>();
045    
046        private final Map<String, String> mimetype2suffix = new HashMap<String, String>();
047    
048        private final Map<String, String> suffix2mimetype = new HashMap<String, String>();
049    
050        /**
051         * Default constructor.
052         */
053        @SuppressWarnings("unchecked")
054        protected ConverterRegistry() {
055            final Iterator<ConverterDetector> it = Service
056                    .providers(ConverterDetector.class);
057            while (it.hasNext()) {
058                final ConverterDetector det = it.next();
059                det.detectConversionPlugins(this);
060            }
061        }
062    
063        /**
064         * Retrieve the default registry instance.
065         * 
066         * @return the ConverterRegistry.
067         */
068        public static ConverterRegistry getInstance() {
069            return ConverterRegistry.SingletonHolder.INSTANCE;
070        }
071    
072        /**
073         * use {@link #getInstance()} instead.
074         * 
075         * @return see {@link #getInstance()}
076         * @deprecated use {@link #getInstance()} instead.
077         */
078        @Deprecated
079        public static ConverterRegistry getRegisty() {
080            return ConverterRegistry.getInstance();
081        }
082    
083        /**
084         * Retrieve a list of available mime types for conversion.
085         * 
086         * @return a Set&lt;String&gt; containing all valid mime-types.
087         */
088        public Set<String> getAvailableOutfileTypes() {
089            return this.mimetype2converter.keySet();
090        }
091    
092        /**
093         * Retrieve a list of all available extensions.
094         * 
095         * @return a list of available extensions.
096         */
097        public Set<String> getAvailableExtensions() {
098            final Set<String> extensions = new HashSet<String>();
099            for (final Map.Entry<String, String> e : this.suffix2mimetype
100                    .entrySet()) {
101                if (this.mimetype2converter.containsKey(e.getValue())) {
102                    extensions.add(e.getKey());
103                }
104            }
105            return extensions;
106        }
107    
108        /**
109         * Returns the file suffix suitable for the given mime type.
110         * <p>
111         * This function is not fully implemented yet
112         * 
113         * @param mimeType
114         *            a mimetype, as returned by {@link #getAvailableOutfileTypes()}
115         *            , or null if unknown.
116         * @return the three letter suffix common for this type.
117         */
118        public String getSuffixForMimeType(final String mimeType) {
119            return this.mimetype2suffix.get(mimeType.toLowerCase(Locale.ENGLISH));
120        }
121    
122        /**
123         * Returns the MimeType for a given suffix.
124         * 
125         * @param suffix
126         *            the suffix, e.g. png, or null if unknown.
127         * @return the mime-type
128         */
129        public String getMimeTypeForSuffix(final String suffix) {
130            return this.suffix2mimetype.get(suffix.toLowerCase(Locale.ENGLISH));
131        }
132    
133        /**
134         * Registers a new MimeType and it's suffix.
135         * 
136         * @param mimeType
137         *            the Mime-Type
138         * @param suffix
139         *            The Suffix
140         * @param primary
141         *            If true, old mappings will be overwritten. If false and a
142         *            mapping already exists, it will stay the same.
143         */
144        public void registerMimeTypeAndSuffix(final String mimeType,
145                final String suffix, final boolean primary) {
146    
147            final String lMimeType = mimeType.toLowerCase(Locale.ENGLISH);
148            final String lSuffix = suffix.toLowerCase(Locale.ENGLISH);
149    
150            if (primary || !this.suffix2mimetype.containsKey(lSuffix)) {
151                this.suffix2mimetype.put(lSuffix, lMimeType);
152            }
153            if (primary || !this.mimetype2suffix.containsKey(lMimeType)) {
154                this.mimetype2suffix.put(lMimeType, lSuffix);
155            }
156        }
157    
158        /**
159         * Registers a converter for the given mime type.
160         * 
161         * @param mimeType
162         *            The mime type.
163         * @param converter
164         *            The converter to register.
165         * @param primary
166         *            Converter for this type. If true, old mappings will be
167         *            overwritten. If false and a mapping already exists, it will
168         *            stay the same.
169         */
170        public void registerConverter(final String mimeType,
171                final ConverterPlugin converter, final boolean primary) {
172            if (primary || !this.mimetype2converter.containsKey(mimeType)) {
173                this.mimetype2converter.put(mimeType, converter);
174            }
175        }
176    
177        /**
178         * Retrieve the converter for a given mime-type.
179         * 
180         * @param mimeType
181         *            the Mime-Type.
182         * @return a Converter instance
183         */
184        public ConverterPlugin getConverter(final String mimeType) {
185            return this.mimetype2converter
186                    .get(mimeType.toLowerCase(Locale.ENGLISH));
187        }
188    }