1/*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.activation;
27
28import java.util.Map;
29import java.util.WeakHashMap;
30
31
32/**
33 * The CommandMap class provides an interface to a registry of
34 * command objects available in the system.
35 * Developers are expected to either use the CommandMap
36 * implementation included with this package (MailcapCommandMap) or
37 * develop their own. Note that some of the methods in this class are
38 * abstract.
39 *
40 * @since 1.6
41 */
42public abstract class CommandMap {
43    private static CommandMap defaultCommandMap = null;
44    private static Map<ClassLoader,CommandMap> map =
45                                new WeakHashMap<ClassLoader,CommandMap>();
46
47    /**
48     * Get the default CommandMap.
49     *
50     * <ul>
51     * <li> In cases where a CommandMap instance has been previously set
52     *      to some value (via <i>setDefaultCommandMap</i>)
53     *  return the CommandMap.
54     * <li>
55     *  In cases where no CommandMap has been set, the CommandMap
56     *       creates an instance of {@code MailcapCommandMap} and
57     *       set that to the default, returning its value.
58     *
59     * </ul>
60     *
61     * @return the CommandMap
62     */
63    public static synchronized CommandMap getDefaultCommandMap() {
64        if (defaultCommandMap != null)
65            return defaultCommandMap;
66
67        // fetch per-thread-context-class-loader default
68        ClassLoader tccl = SecuritySupport.getContextClassLoader();
69        CommandMap def = map.get(tccl);
70        if (def == null) {
71            def = new MailcapCommandMap();
72            map.put(tccl, def);
73        }
74        return def;
75    }
76
77    /**
78     * Set the default CommandMap. Reset the CommandMap to the default by
79     * calling this method with {@code null}.
80     *
81     * @param commandMap The new default CommandMap.
82     * @exception SecurityException if the caller doesn't have permission
83     *                                  to change the default
84     */
85    public static synchronized void setDefaultCommandMap(CommandMap commandMap) {
86        SecurityManager security = System.getSecurityManager();
87        if (security != null) {
88            try {
89                // if it's ok with the SecurityManager, it's ok with me...
90                security.checkSetFactory();
91            } catch (SecurityException ex) {
92                // otherwise, we also allow it if this code and the
93                // factory come from the same (non-system) class loader (e.g.,
94                // the JAF classes were loaded with the applet classes).
95                ClassLoader cl = CommandMap.class.getClassLoader();
96                if (cl == null || cl.getParent() == null ||
97                    cl != commandMap.getClass().getClassLoader()) {
98                    throw ex;
99                }
100            }
101        }
102        // remove any per-thread-context-class-loader CommandMap
103        map.remove(SecuritySupport.getContextClassLoader());
104        defaultCommandMap = commandMap;
105    }
106
107    /**
108     * Get the preferred command list from a MIME Type. The actual semantics
109     * are determined by the implementation of the CommandMap.
110     *
111     * @param mimeType  the MIME type
112     * @return the CommandInfo classes that represent the command Beans.
113     */
114    abstract public  CommandInfo[] getPreferredCommands(String mimeType);
115
116    /**
117     * Get the preferred command list from a MIME Type. The actual semantics
118     * are determined by the implementation of the CommandMap. <p>
119     *
120     * The {@code DataSource} provides extra information, such as
121     * the file name, that a CommandMap implementation may use to further
122     * refine the list of commands that are returned.  The implementation
123     * in this class simply calls the {@code getPreferredCommands}
124     * method that ignores this argument.
125     *
126     * @param mimeType  the MIME type
127     * @param ds        a DataSource for the data
128     * @return the CommandInfo classes that represent the command Beans.
129     * @since   1.6, JAF 1.1
130     */
131    public CommandInfo[] getPreferredCommands(String mimeType, DataSource ds) {
132        return getPreferredCommands(mimeType);
133    }
134
135    /**
136     * Get all the available commands for this type. This method
137     * should return all the possible commands for this MIME type.
138     *
139     * @param mimeType  the MIME type
140     * @return the CommandInfo objects representing all the commands.
141     */
142    abstract public CommandInfo[] getAllCommands(String mimeType);
143
144    /**
145     * Get all the available commands for this type. This method
146     * should return all the possible commands for this MIME type. <p>
147     *
148     * The {@code DataSource} provides extra information, such as
149     * the file name, that a CommandMap implementation may use to further
150     * refine the list of commands that are returned.  The implementation
151     * in this class simply calls the {@code getAllCommands}
152     * method that ignores this argument.
153     *
154     * @param mimeType  the MIME type
155     * @param ds        a DataSource for the data
156     * @return the CommandInfo objects representing all the commands.
157     * @since   1.6, JAF 1.1
158     */
159    public CommandInfo[] getAllCommands(String mimeType, DataSource ds) {
160        return getAllCommands(mimeType);
161    }
162
163    /**
164     * Get the default command corresponding to the MIME type.
165     *
166     * @param mimeType  the MIME type
167     * @param cmdName   the command name
168     * @return the CommandInfo corresponding to the command.
169     */
170    abstract public CommandInfo getCommand(String mimeType, String cmdName);
171
172    /**
173     * Get the default command corresponding to the MIME type. <p>
174     *
175     * The {@code DataSource} provides extra information, such as
176     * the file name, that a CommandMap implementation may use to further
177     * refine the command that is chosen.  The implementation
178     * in this class simply calls the {@code getCommand}
179     * method that ignores this argument.
180     *
181     * @param mimeType  the MIME type
182     * @param cmdName   the command name
183     * @param ds        a DataSource for the data
184     * @return the CommandInfo corresponding to the command.
185     * @since   1.6, JAF 1.1
186     */
187    public CommandInfo getCommand(String mimeType, String cmdName,
188                                DataSource ds) {
189        return getCommand(mimeType, cmdName);
190    }
191
192    /**
193     * Locate a DataContentHandler that corresponds to the MIME type.
194     * The mechanism and semantics for determining this are determined
195     * by the implementation of the particular CommandMap.
196     *
197     * @param mimeType  the MIME type
198     * @return          the DataContentHandler for the MIME type
199     */
200    abstract public DataContentHandler createDataContentHandler(String
201                                                                mimeType);
202
203    /**
204     * Locate a DataContentHandler that corresponds to the MIME type.
205     * The mechanism and semantics for determining this are determined
206     * by the implementation of the particular CommandMap. <p>
207     *
208     * The {@code DataSource} provides extra information, such as
209     * the file name, that a CommandMap implementation may use to further
210     * refine the choice of DataContentHandler.  The implementation
211     * in this class simply calls the {@code createDataContentHandler}
212     * method that ignores this argument.
213     *
214     * @param mimeType  the MIME type
215     * @param ds        a DataSource for the data
216     * @return          the DataContentHandler for the MIME type
217     * @since   1.6, JAF 1.1
218     */
219    public DataContentHandler createDataContentHandler(String mimeType,
220                                DataSource ds) {
221        return createDataContentHandler(mimeType);
222    }
223
224    /**
225     * Get all the MIME types known to this command map.
226     * If the command map doesn't support this operation,
227     * null is returned.
228     *
229     * @return          array of MIME types as strings, or null if not supported
230     * @since   1.6, JAF 1.1
231     */
232    public String[] getMimeTypes() {
233        return null;
234    }
235}
236