//$Id: GoogleCorePlugin.java,v 1.3 2005/06/21 15:47:56 cvsuser Exp $
//作成日: 2005/03/02
package nu.mine.kino.plugin.google.core;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.rmi.RemoteException;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.xml.rpc.ServiceException;

import nu.mine.kino.googleapis.GoogleSearchPort;
import nu.mine.kino.googleapis.GoogleSearchResult;
import nu.mine.kino.googleapis.GoogleSearchServiceLocator;

import org.apache.log4j.Logger;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;

/**
 * Google検索を行うプラグインです。
 * 
 * @author Masatomi KINO
 * @version $Revision: 1.3 $
 */
public class GoogleCorePlugin extends Plugin {
    /**
     * Logger for this class
     */
    private static final Logger logger = Logger
            .getLogger(GoogleCorePlugin.class);

    private GoogleSearchPort googleSearch;

    // The shared instance.
    private static GoogleCorePlugin plugin;

    // Resource bundle.
    private ResourceBundle resourceBundle;

    /**
     * The constructor.
     */
    public GoogleCorePlugin() {
        super();
        plugin = this;
        try {
            resourceBundle = ResourceBundle
                    .getBundle("nu.mine.kino.plugin.google.core.GoogleCorePluginResources");
        } catch (MissingResourceException x) {
            resourceBundle = null;
        }
    }

    /**
     * プラグインの活性化時に呼ばれます。 This method is called upon plug-in activation
     */
    public void start(BundleContext context) throws Exception {
        logger.debug("start(BundleContext) - start");
        super.start(context);

        try {
            GoogleSearchServiceLocator locator = new GoogleSearchServiceLocator();
            googleSearch = locator.getGoogleSearchPort();
        } catch (ServiceException e) {
            logger.error(e);
            log(e);
        }

        logger.debug("start(BundleContext) - end");
    }

    /**
     * This method is called when the plug-in is stopped
     */
    public void stop(BundleContext context) throws Exception {
        super.stop(context);
    }

    /**
     * Returns the shared instance.
     */
    public static GoogleCorePlugin getDefault() {
        return plugin;
    }

    /**
     * Returns the string from the plugin's resource bundle, or 'key' if not
     * found.
     */
    public static String getResourceString(String key) {
        ResourceBundle bundle = GoogleCorePlugin.getDefault()
                .getResourceBundle();
        try {
            return (bundle != null) ? bundle.getString(key) : key;
        } catch (MissingResourceException e) {
            return key;
        }
    }

    /**
     * Returns the plugin's resource bundle,
     */
    public ResourceBundle getResourceBundle() {
        return resourceBundle;
    }

    /**
     * 引数の文字列でGoogle検索を行います。エラーが発生した場合nullが返るか、例外を投げます。
     * 
     * @param myGoogleKey
     *            Googleのキー
     * @param searchText
     *            検索文字列
     * @return GoogleSearchResult
     * @throws CoreException
     *             何らかのエラーが発生したとき。
     */
    public GoogleSearchResult search(String myGoogleKey, String searchText)
            throws CoreException {
        logger.debug("search(String) - start");

        GoogleSearchResult result = null;
        if (googleSearch != null) {
            try {
                result = googleSearch.doGoogleSearch(myGoogleKey, searchText,
                        1, 10, false, "", false, "lang_ja", "", "");
            } catch (RemoteException e) {
                logger.error(e);
                log(e);
                IStatus status = new Status(IStatus.ERROR, getPluginId(),
                        IStatus.ERROR, e.toString(), e);
                throw new CoreException(status);
            }
        }
        logger.debug("search(String) - end");
        return result;
    }

    /**
     * 引数の文字列にスペルミスがないかをチェックするメソッドです。 スペルミスがある場合、候補を返します。スペルミスがない場合、nullが返ります。
     * 
     * @param myGoogleKey
     * @param text
     * @return
     */
    public String getSplellingSuggestion(String myGoogleKey, String text) {
        logger.debug("getSplellingSuggestion(String, String) - start");

        String suggestionText = null;
        try {
            suggestionText = googleSearch.doSpellingSuggestion(myGoogleKey,
                    text);
        } catch (Exception e) {
            // 文字によっては例外が発生するので、その場合は
            // とりあえず候補がなかったことにして通り過ぎちゃう
            logger.warn(e);
            logger.warn("スペルミス補正でエラーが発生しました。");
        }

        logger.debug("getSplellingSuggestion(String, String) - end");
        return suggestionText;
    }

    public static void log(String message, Exception e) {
        IStatus status = new Status(IStatus.ERROR, getPluginId(),
                IStatus.ERROR, message, e);
        getDefault().getLog().log(status);
    }

    public static void log(String message) {
        log(message, null);
    }

    public static void log(Exception e) {
        StringWriter stringWriter = new StringWriter();
        e.printStackTrace(new PrintWriter(stringWriter));
        String message = stringWriter.getBuffer().toString();
        log(message, e);
    }

    public static String getPluginId() {
        return getDefault().getBundle().getSymbolicName();
    }

}