aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
blob: ebf29d19ccbf25e5a662cf2c476a4196fbe7f282 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package cgeo.geocaching.loaders;

import cgeo.geocaching.SearchResult;
import cgeo.geocaching.connector.gc.GCConstants;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.TextUtils;

import org.apache.commons.lang3.StringUtils;

import android.content.Context;
import android.os.Handler;
import android.support.v4.content.AsyncTaskLoader;

public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult> implements RecaptchaReceiver {

    public enum CacheListLoaderType {
        OFFLINE,
        HISTORY,
        NEAREST,
        COORDINATE,
        KEYWORD,
        ADDRESS,
        USERNAME,
        OWNER,
        MAP,
        REMOVE_FROM_HISTORY,
        NEXT_PAGE;
    }

    private Handler recaptchaHandler = null;
    private String recaptchaChallenge = null;
    private String recaptchaKey = null;
    private String recaptchaText = null;
    private SearchResult search;
    private boolean loading;

    public AbstractSearchLoader(Context context) {
        super(context);
    }

    public abstract SearchResult runSearch();

    public boolean isLoading() {
        return loading;
    }

    @Override
    public SearchResult loadInBackground() {
        loading = true;
        try {
            if (search == null) {
                search = runSearch();
            } else {
                // Unless we make a new Search the Loader framework won't deliver results. It does't do equals only identity
                search = new SearchResult(search);
            }
        } catch (Exception e) {
            Log.e("Error in Loader ", e);
        }
        loading = false;
        if (search == null) {
            search = new SearchResult();
        }
        return search;
    }

    @Override
    public boolean takeContentChanged() {
        return super.takeContentChanged();
    }

    @Override
    protected void onStartLoading() {
        forceLoad();
    }

    public void setRecaptchaHandler(Handler recaptchaHandlerIn) {
        recaptchaHandler = recaptchaHandlerIn;
    }

    @Override
    public void notifyNeed() {
        if (recaptchaHandler != null) {
            recaptchaHandler.sendEmptyMessage(1);
        }
    }

    @Override
    public synchronized void waitForUser() {
        try {
            wait();
        } catch (InterruptedException e) {
            Log.w("searchThread is not waiting for user…");
        }
    }

    @Override
    public void setKey(String key) {
        recaptchaKey = key;
    }

    @Override
    public String getKey() {
        return recaptchaKey;
    }

    @Override
    public void fetchChallenge() {
        recaptchaChallenge = null;

        if (StringUtils.isNotEmpty(recaptchaKey)) {
            final Parameters params = new Parameters("k", getKey());
            final String recaptchaJs = Network.getResponseData(Network.getRequest("http://www.google.com/recaptcha/api/challenge", params));

            if (StringUtils.isNotBlank(recaptchaJs)) {
                recaptchaChallenge = TextUtils.getMatch(recaptchaJs, GCConstants.PATTERN_SEARCH_RECAPTCHACHALLENGE, true, 1, null, true);
            }
        }
    }

    @Override
    public String getChallenge() {
        return recaptchaChallenge;
    }

    @Override
    public synchronized void setText(String text) {
        recaptchaText = text;

        notify();
    }

    @Override
    public synchronized String getText() {
        return recaptchaText;
    }


    @Override
    public void reset() {
        super.reset();
        search = null;
    }
}