001package icy.network;
002
003import java.io.IOException;
004import java.io.UnsupportedEncodingException;
005import java.net.URLEncoder;
006import java.util.HashMap;
007import java.util.Map;
008
009import org.w3c.dom.Document;
010
011import icy.main.Icy;
012import icy.math.UnitUtil;
013import icy.plugin.PluginDescriptor;
014import icy.plugin.PluginDescriptor.PluginIdent;
015import icy.plugin.PluginLauncher;
016import icy.plugin.PluginLoader;
017import icy.plugin.interface_.PluginBundled;
018import icy.preferences.ApplicationPreferences;
019import icy.system.IcyExceptionHandler;
020import icy.system.SystemUtil;
021import icy.system.thread.ThreadUtil;
022import icy.util.StringUtil;
023import icy.util.XMLUtil;
024
025public class WebInterface
026{
027    public static final String BASE_URL = NetworkUtil.WEBSITE_URL + "interface/";
028
029    public static final String PARAM_ACTION = "action";
030    public static final String PARAM_CLIENT_ID = "clientId";
031    public static final String PARAM_ID = "id";
032    public static final String PARAM_CLASSNAME = "classname";
033    public static final String PARAM_FIELD = "field";
034
035    // search specific parameter(s)
036    public static final String PARAM_SEARCH = "search";
037    public static final String PARAM_POSTTYPE = "pt";
038
039    // bug report specific parameter(s)
040    public static final String PARAM_KERNELVERSION = "kernelVersion";
041    public static final String PARAM_JAVANAME = "javaName";
042    public static final String PARAM_JAVAVERSION = "javaVersion";
043    public static final String PARAM_JAVABITS = "javaBits";
044    public static final String PARAM_OSNAME = "osName";
045    public static final String PARAM_OSVERSION = "osVersion";
046    public static final String PARAM_OSARCH = "osArch";
047    public static final String PARAM_PLUGINCLASSNAME = "pluginClassName";
048    public static final String PARAM_PLUGINVERSION = "pluginVersion";
049    public static final String PARAM_DEVELOPERID = "developerId";
050    public static final String PARAM_ERRORLOG = "errorLog";
051
052    // action types
053    public static final String ACTION_TYPE_SEARCH = "search";
054    public static final String ACTION_TYPE_BUGREPORT = "bugReport";
055    // search types
056    public static final String SEARCH_TYPE_PLUGIN = "plugin";
057    public static final String SEARCH_TYPE_SCRIPT = "script";
058    public static final String SEARCH_TYPE_PROTOCOL = "protocol";
059
060    /**
061     * Process search on the website in a specific resource and return result in a XML Document.
062     * 
063     * @param text
064     *        Text used for the search request, it can contains several words and use operators.<br>
065     *        Examples:<br>
066     *        <li><i>spot detector</i> : any of word should be present</li>
067     *        <li><i>+spot +detector</i> : both words should be present</li>
068     *        <li>"spot detector"</i> : the exact expression should be present</li>
069     *        <li><i>+"spot detector" -tracking</i> : <i>spot detector</i> should be present and <i>tracking</i> absent</li>
070     * @param type
071     *        type of resource we want to search in.<br>
072     *        Accepted values are:<br>
073     *        <li>SEARCH_TYPE_PLUGIN</li>
074     *        <li>SEARCH_TYPE_SCRIPT</li>
075     *        <li>SEARCH_TYPE_PROTOCOL</li>
076     *        <li>null (all resources)</li>
077     * @return result in XML Document format
078     * @throws UnsupportedEncodingException
079     */
080    public static Document doSearch(String text, String type) throws UnsupportedEncodingException
081    {
082        // build request (encode search text in UTF8)
083        String request = BASE_URL + " ?" + PARAM_ACTION + "=" + ACTION_TYPE_SEARCH + "&" + PARAM_SEARCH + "="
084                + URLEncoder.encode(text, "UTF-8");
085
086        // specific type ?
087        if (!StringUtil.isEmpty(type))
088            request += "&" + PARAM_POSTTYPE + "=" + type;
089
090        // add client id
091        // request += "&" + PARAM_CLIENT_ID + "=2532495";
092        request += "&" + PARAM_CLIENT_ID + "=" + ApplicationPreferences.getId();
093
094        // send request to web site and get result
095        return XMLUtil.loadDocument(URLUtil.getURL(request), true);
096    }
097
098    /**
099     * Process search on the website in all resources and return result in a XML Document.
100     * 
101     * @param text
102     *        Text used for the search request, it can contains several words and use operators.<br>
103     *        Examples:<br>
104     *        <li><i>spot detector</i> : any of word should be present</li>
105     *        <li><i>+spot +detector</i> : both words should be present</li>
106     *        <li>"spot detector"</i> : the exact expression should be present</li>
107     *        <li><i>+"spot detector" -tracking</i> : <i>spot detector</i> should be present and <i>tracking</i> absent</li>
108     * @return result in XML Document format
109     * @throws UnsupportedEncodingException
110     */
111    public static Document doSearch(String text) throws UnsupportedEncodingException
112    {
113        return doSearch(text, null);
114    }
115
116    /**
117     * Report an error log from a given plugin or developer id to Icy web site.
118     * 
119     * @param plugin
120     *        The plugin responsible of the error or <code>null</code> if the error comes from the
121     *        application or if we are not able to get the plugin descriptor.
122     * @param devId
123     *        The developer id of the plugin responsible of the error when the plugin descriptor was
124     *        not found or <code>null</code> if the error comes from the application.
125     * @param errorLog
126     *        Error log to report.
127     */
128    public static void reportError(PluginDescriptor plugin, String devId, String errorLog)
129    {
130        final String icyId;
131        final String javaId;
132        final String osId;
133        final String memory;
134        String pluginId;
135        String pluginDepsId;
136        final Map<String, String> values = new HashMap<String, String>();
137
138        // bug report action
139        values.put(PARAM_ACTION, ACTION_TYPE_BUGREPORT);
140
141        // add informations about java / system / OS
142        values.put(PARAM_KERNELVERSION, Icy.version.toString());
143        values.put(PARAM_JAVANAME, SystemUtil.getJavaName());
144        values.put(PARAM_JAVAVERSION, SystemUtil.getJavaVersion());
145        values.put(PARAM_JAVABITS, Integer.toString(SystemUtil.getJavaArchDataModel()));
146        values.put(PARAM_OSNAME, SystemUtil.getOSName());
147        values.put(PARAM_OSVERSION, SystemUtil.getOSVersion());
148        values.put(PARAM_OSARCH, SystemUtil.getOSArch());
149
150        icyId = "Icy Version " + Icy.version + "\n";
151        javaId = SystemUtil.getJavaName() + " " + SystemUtil.getJavaVersion() + " (" + SystemUtil.getJavaArchDataModel()
152                + " bit)\n";
153        osId = "Running on " + SystemUtil.getOSName() + " " + SystemUtil.getOSVersion() + " (" + SystemUtil.getOSArch()
154                + ")\n";
155        memory = "Max java memory : " + UnitUtil.getBytesString(SystemUtil.getJavaMaxMemory()) + "\n";
156
157        if (plugin != null)
158        {
159            final String className = plugin.getClassName();
160
161            // add plugin informations if available
162            values.put(PARAM_PLUGINCLASSNAME, className);
163            values.put(PARAM_PLUGINVERSION, plugin.getVersion().toString());
164
165            pluginId = "Plugin " + plugin.toString();
166            // determine origin plugin
167            PluginDescriptor originPlugin = plugin;
168
169            // bundled plugin ?
170            if (plugin.isBundled())
171            {
172                try
173                {
174                    // get original plugin
175                    originPlugin = PluginLoader
176                            .getPlugin(((PluginBundled) PluginLauncher.create(plugin)).getMainPluginClassName());
177                    // add bundle info
178                    pluginId = "Bundled in " + originPlugin.toString();
179                }
180                catch (Throwable t)
181                {
182                    // miss bundle info
183                    pluginId = "Bundled plugin (could not retrieve origin plugin)";
184                }
185            }
186
187            pluginId += "\n\n";
188
189            if (originPlugin.getRequired().size() > 0)
190            {
191                pluginDepsId = "Dependances:\n";
192                for (PluginIdent ident : originPlugin.getRequired())
193                {
194                    final PluginDescriptor installed = PluginLoader.getPlugin(ident.getClassName());
195
196                    if (installed == null)
197                        pluginDepsId += "Class " + ident.getClassName() + " not found !\n";
198                    else
199                        pluginDepsId += "Plugin " + installed.toString() + " is correctly installed\n";
200                }
201                pluginDepsId += "\n";
202            }
203            else
204                pluginDepsId = "";
205        }
206        else
207        {
208            // no plugin information available
209            values.put(PARAM_PLUGINCLASSNAME, "");
210            values.put(PARAM_PLUGINVERSION, "");
211            pluginId = "";
212            pluginDepsId = "";
213        }
214
215        // add dev id
216        if (StringUtil.isEmpty(devId))
217            values.put(PARAM_DEVELOPERID, devId);
218        else
219            values.put(PARAM_DEVELOPERID, "");
220
221        // add client id
222        values.put(PARAM_CLIENT_ID, "2532495");
223        // values.put(PARAM_CLIENT_ID, Integer.toString(ApplicationPreferences.getId()));
224
225        // and finally the error log itself
226        values.put(PARAM_ERRORLOG, icyId + javaId + osId + memory + "\n" + pluginId + pluginDepsId + errorLog);
227
228        // TODO: change when ready !
229        // NetworkUtil.report(values);
230
231        // send report in background task (we don't want to wait for response from server)
232        ThreadUtil.bgRun(new Runnable()
233        {
234            @Override
235            public void run()
236            {
237                try
238                {
239                    final String result = NetworkUtil.postData(BASE_URL, values);
240
241                    if (result == null)
242                        System.out.println("Error while reporting data, verifying your internet connection.");
243                }
244                catch (IOException e)
245                {
246                    System.out.println("Error while reporting data :");
247                    IcyExceptionHandler.showErrorMessage(e, false, false);
248                }
249            }
250        });
251    }
252}