1/*
2    Copyright (C) 2000 Harri Porten (porten@kde.org)
3    Copyright (C) 2000 Daniel Molkentin (molkentin@kde.org)
4    Copyright (C) 2000 Stefan Schimanski (schimmi@kde.org)
5    Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All Rights Reserved.
6    Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
7
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Library General Public
10    License as published by the Free Software Foundation; either
11    version 2 of the License, or (at your option) any later version.
12
13    This library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Library General Public License for more details.
17
18    You should have received a copy of the GNU Library General Public License
19    along with this library; see the file COPYING.LIB.  If not, write to
20    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.
22*/
23
24#include "config.h"
25#include "platform/plugins/PluginData.h"
26
27#include "platform/plugins/PluginListBuilder.h"
28#include "public/platform/Platform.h"
29
30namespace blink {
31
32class PluginCache {
33public:
34    PluginCache() : m_loaded(false), m_refresh(false) { }
35    ~PluginCache() { reset(false); }
36
37    void reset(bool refresh)
38    {
39        m_plugins.clear();
40        m_loaded = false;
41        m_refresh = refresh;
42    }
43
44    const Vector<PluginInfo>& plugins()
45    {
46        if (!m_loaded) {
47            PluginListBuilder builder(&m_plugins);
48            blink::Platform::current()->getPluginList(m_refresh, &builder);
49            m_loaded = true;
50            m_refresh = false;
51        }
52        return m_plugins;
53    }
54
55private:
56    Vector<PluginInfo> m_plugins;
57    bool m_loaded;
58    bool m_refresh;
59};
60
61static PluginCache& pluginCache()
62{
63    DEFINE_STATIC_LOCAL(PluginCache, cache, ());
64    return cache;
65}
66
67PluginData::PluginData(const Page* page)
68{
69    initPlugins(page);
70
71    for (unsigned i = 0; i < m_plugins.size(); ++i) {
72        const PluginInfo& plugin = m_plugins[i];
73        for (unsigned j = 0; j < plugin.mimes.size(); ++j) {
74            m_mimes.append(plugin.mimes[j]);
75            m_mimePluginIndices.append(i);
76        }
77    }
78}
79
80bool PluginData::supportsMimeType(const String& mimeType) const
81{
82    for (unsigned i = 0; i < m_mimes.size(); ++i)
83        if (m_mimes[i].type == mimeType)
84            return true;
85    return false;
86}
87
88const PluginInfo* PluginData::pluginInfoForMimeType(const String& mimeType) const
89{
90    for (unsigned i = 0; i < m_mimes.size(); ++i) {
91        const MimeClassInfo& info = m_mimes[i];
92
93        if (info.type == mimeType)
94            return &m_plugins[m_mimePluginIndices[i]];
95    }
96
97    return 0;
98}
99
100String PluginData::pluginNameForMimeType(const String& mimeType) const
101{
102    if (const PluginInfo* info = pluginInfoForMimeType(mimeType))
103        return info->name;
104    return String();
105}
106
107String PluginData::pluginFileForMimeType(const String& mimeType) const
108{
109    if (const PluginInfo* info = pluginInfoForMimeType(mimeType))
110        return info->file;
111    return String();
112}
113
114void PluginData::initPlugins(const Page*)
115{
116    const Vector<PluginInfo>& plugins = pluginCache().plugins();
117    for (size_t i = 0; i < plugins.size(); ++i)
118        m_plugins.append(plugins[i]);
119}
120
121void PluginData::refresh()
122{
123    pluginCache().reset(true);
124    pluginCache().plugins(); // Force the plugins to be reloaded now.
125}
126
127String getPluginMimeTypeFromExtension(const String& extension)
128{
129    const Vector<PluginInfo>& plugins = pluginCache().plugins();
130    for (size_t i = 0; i < plugins.size(); ++i) {
131        for (size_t j = 0; j < plugins[i].mimes.size(); ++j) {
132            const MimeClassInfo& mime = plugins[i].mimes[j];
133            const Vector<String>& extensions = mime.extensions;
134            for (size_t k = 0; k < extensions.size(); ++k) {
135                if (extension == extensions[k])
136                    return mime.type;
137            }
138        }
139    }
140    return String();
141}
142
143}
144