requesting added

This commit is contained in:
Gavriil Sitnikov 2015-11-13 17:39:39 +03:00
parent 5d823d73a8
commit 1515d059b7
8 changed files with 417 additions and 6 deletions

View File

@ -26,9 +26,19 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.facebook.fresco:fbcore:0.7.0'
compile 'io.reactivex:rxandroid:1.0.1'
compile project(':libraries:core')
provided 'com.android.support:appcompat-v7:23.1.0'
provided 'io.reactivex:rxandroid:1.0.1'
provided('com.google.http-client:google-http-client-android:1.20.0') {
exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
}
provided('com.google.http-client:google-http-client-jackson2:1.20.0') {
exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
}
provided 'com.squareup.okhttp:okhttp:2.5.0'
provided 'com.facebook.fresco:fbcore:0.7.0'
}
apply from: "${rootDir}/libraries/BuildScripts/gradle/staticAnalysis.gradle"

View File

@ -26,13 +26,15 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
/**
* Created by Gavriil Sitnikov on 21/10/2015.
* TODO: fill description
*/
public abstract class BaseFragment<TViewHolder extends BaseFragment.ViewHolder> extends Fragment
public abstract class BaseFragment<TViewHolder extends BaseFragment.ViewController> extends Fragment
implements OnFragmentStartedListener {
@Nullable
@ -118,6 +120,11 @@ public abstract class BaseFragment<TViewHolder extends BaseFragment.ViewHolder>
return result;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
/* Raises when ActionBar home button pressed */
public boolean onHomePressed() {
FragmentManager fragmentManager = getChildFragmentManager();
@ -178,7 +185,7 @@ public abstract class BaseFragment<TViewHolder extends BaseFragment.ViewHolder>
viewHolder.onDestroy();
}
public class ViewHolder {
public class ViewController {
private final Context context;
private final Handler postHandler = new Handler();
@ -194,7 +201,7 @@ public abstract class BaseFragment<TViewHolder extends BaseFragment.ViewHolder>
return context;
}
public ViewHolder(@NonNull View view){
public ViewController(@NonNull View view) {
context = view.getContext();
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
*
* This file is part of RoboSwag library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.roboswag.components.requests;
import android.support.annotation.NonNull;
import com.squareup.okhttp.Request;
import java.io.IOException;
/**
* Created by Gavriil Sitnikov on 07/14.
* Get request that returns data in JSON format
*/
public abstract class AbstractGetJsonRequest<T> extends AbstractJsonRequest<T> {
protected AbstractGetJsonRequest(@NonNull final Class<T> responseResultType) {
super(responseResultType);
}
@NonNull
@Override
protected Request.Builder createHttpRequest() throws IOException {
return super.createHttpRequest().get();
}
}

View File

@ -0,0 +1,182 @@
/*
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
*
* This file is part of RoboSwag library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.roboswag.components.requests;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.util.Charsets;
import com.google.api.client.util.ObjectParser;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import org.roboswag.core.log.Lc;
import org.roboswag.core.log.LcHelper;
import org.roboswag.core.utils.ShouldNotHappenException;
import org.roboswag.core.utils.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import okio.Buffer;
import rx.Observable;
import rx.schedulers.Schedulers;
/**
* Created by Gavriil Sitnikov on 13/11/2015.
* TODO: fill description
*/
public abstract class AbstractHttpRequest<T> {
private static final String CACHE_PARAMETER_SEPARATOR = "#";
private static final int CACHE_MAX_KEY_SIZE = 128;
@NonNull
private final Class<T> responseResultType;
private Request request;
private Call call;
protected AbstractHttpRequest(@NonNull final Class<T> responseResultType) {
this.responseResultType = responseResultType;
}
@NonNull
public Class<T> getResponseResultType() {
return responseResultType;
}
/* Returns data parser */
protected abstract ObjectParser getParser() throws Exception;
@NonNull
protected abstract String getUrl();
protected void setupUrlParameters(@NonNull final GenericUrl url) {
// to be overridden. default does nothing
}
@NonNull
protected OkHttpClient createHttpClient() {
return new OkHttpClient();
}
@NonNull
protected Request.Builder createHttpRequest() throws IOException {
final GenericUrl genericUrl = new GenericUrl(getUrl());
setupUrlParameters(genericUrl);
return new Request.Builder().url(genericUrl.build());
}
@NonNull
private Request getRequest() throws IOException {
if (request == null) {
request = createHttpRequest().build();
}
return request;
}
public void cancel() {
if (call != null && !call.isCanceled()) {
call.cancel();
}
}
@NonNull
public T executeSync() throws Exception {
final Request request = getRequest();
if (LcHelper.getLogLevel() <= Log.DEBUG) {
Lc.d("Url requested: %s\n%s", request.url(), requestBodyToString(request));
}
call = createHttpClient().newCall(request);
final Response response = call.execute();
final ResponseBody responseBody = response.body();
final byte[] bytes = responseBody.bytes();
final Charset charset = getCharset(responseBody);
if (LcHelper.getLogLevel() <= Log.DEBUG) {
Lc.d("Response for: %s has code %s and content: %s", request.url(), response.code(), new String(bytes, charset));
}
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
T result = getParser().parseAndClose(byteArrayInputStream, charset, responseResultType);
result = handleResponse(result);
return result;
}
@NonNull
public Observable<T> execute() {
return Observable.<T>create(subscriber -> {
try {
subscriber.onNext(executeSync());
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
}).subscribeOn(Schedulers.io());
}
@NonNull
private Charset getCharset(final ResponseBody responseBody) {
final MediaType contentType = responseBody.contentType();
return contentType == null ? Charsets.UTF_8 : contentType.charset(Charsets.UTF_8);
}
private String requestBodyToString(@NonNull final Request request) throws IOException {
final RequestBody body = request.newBuilder().build().body();
if (body == null) {
return "";
}
final Buffer buffer = new Buffer();
body.writeTo(buffer);
return buffer.readUtf8();
}
/* Handle response. Use it to do something after request successfully executes */
@NonNull
protected T handleResponse(final T response) throws Exception {
return response;
}
@NonNull
public String getCacheKey() {
final StringBuilder fileNameSafeCacheKey = new StringBuilder();
try {
final Request request = getRequest();
fileNameSafeCacheKey.append(URLEncoder.encode(request.urlString(), "UTF-8").replace("%", CACHE_PARAMETER_SEPARATOR));
fileNameSafeCacheKey.append(CACHE_PARAMETER_SEPARATOR).append(request.headers());
if (request.body() != null) {
fileNameSafeCacheKey.append(CACHE_PARAMETER_SEPARATOR).append(requestBodyToString(request));
}
} catch (final Exception e) {
throw new ShouldNotHappenException(e);
}
final String cacheKeyMd5 = StringUtils.md5(fileNameSafeCacheKey.toString());
final int length = fileNameSafeCacheKey.length();
return fileNameSafeCacheKey.substring(Math.max(0, length - CACHE_MAX_KEY_SIZE), length) + CACHE_PARAMETER_SEPARATOR + cacheKeyMd5;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
*
* This file is part of RoboSwag library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.roboswag.components.requests;
import android.support.annotation.NonNull;
import com.google.api.client.http.AbstractHttpContent;
import com.google.api.client.http.json.JsonHttpContent;
/**
* Created by Gavriil Sitnikov on 07/14.
* Post request that includes JSON data as content and returns data in JSON format
*/
public abstract class AbstractJsonContentPostJsonRequest<T> extends AbstractPostJsonRequest<T> {
@NonNull
@Override
protected AbstractHttpContent getContent() {
return new JsonHttpContent(DEFAULT_JSON_FACTORY, getContentObject());
}
protected AbstractJsonContentPostJsonRequest(@NonNull final Class<T> responseResultType) {
super(responseResultType);
}
/* Returns content object to store in JSON format */
@NonNull
protected abstract Object getContentObject();
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
*
* This file is part of RoboSwag library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.roboswag.components.requests;
import android.support.annotation.NonNull;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ObjectParser;
/**
* Created by Gavriil Sitnikov on 07/14.
* Request that returns data in JSON format
*/
public abstract class AbstractJsonRequest<T> extends AbstractHttpRequest<T> {
protected static final JsonFactory DEFAULT_JSON_FACTORY = new JacksonFactory();
@NonNull
@Override
protected ObjectParser getParser() {
return DEFAULT_JSON_FACTORY.createJsonObjectParser();
}
protected AbstractJsonRequest(@NonNull final Class<T> responseResultType) {
super(responseResultType);
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
*
* This file is part of RoboSwag library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.roboswag.components.requests;
import android.support.annotation.NonNull;
import com.google.api.client.http.AbstractHttpContent;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* Created by Gavriil Sitnikov on 07/14.
* Post request that returns data in JSON format
*/
public abstract class AbstractPostJsonRequest<T> extends AbstractJsonRequest<T> {
@NonNull
protected abstract AbstractHttpContent getContent();
protected AbstractPostJsonRequest(@NonNull final Class<T> responseResultType) {
super(responseResultType);
}
@NonNull
@Override
protected Request.Builder createHttpRequest() throws IOException {
final AbstractHttpContent content = getContent();
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
getContent().writeTo(byteArrayOutputStream);
return super.createHttpRequest().post(RequestBody.create(
MediaType.parse(content.getMediaType().build()), byteArrayOutputStream.toByteArray()));
}
}

View File

@ -0,0 +1,20 @@
package org.roboswag.components.utils;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Gavriil Sitnikov on 13/11/2015.
* TODO: fill description
*/
public class UiUtils {
@NonNull
public static View inflate(@LayoutRes int layoutId, @NonNull ViewGroup parent) {
return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
}
}