Исходный код программного средства
Листинг В.1 – Исходный код модуля “RealmHelper.java”
public class RealmHelper {
/**
* Realm instance for the UI thread
*/
@Inject
Realm realmUI;
public RealmHelper(Realm realm) {
realmUI = realm;
}
private PublishSubject<Boolean> deleteSubject = PublishSubject.create();
private PublishSubject<Boolean> saveSubject = PublishSubject.create();
public List<Language> readAllSupportLanguages() {
Log.d("tag_", "realUi " + (realmUI == null));
return realmUI
.where(Language.class)
.findAllSorted("fullName");
}
/**
* Remove last response and write new one into realm
*/
public void writeLanguageResponseToRealm(Language language) {
Realm realm = Realm.getDefaultInstance();
realm.executeTransaction(transaction -> {
Language lang = transaction
.where(Language.class)
.equalTo("name", language.getName())
.findFirst();
if (lang == null) {
lang = transaction.createObject(Language.class, language.getName());
}
lang.setFullName(language.getFullName());
});
realm.close();
}
public Observable<Boolean> writeTranslationToRealm(Translation translation) {
Realm realm = Realm.getDefaultInstance();
realm.executeTransaction(
transaction -> {
Translation tr = transaction
.where(Translation.class)
.equalTo("mOriginalText", translation.getOriginalText())
.findFirst();
if (tr == null) {
tr = transaction.createObject(Translation.class);
tr.createFrom(translation, transaction);
tr.setHistory(true);
} else {
tr.update();
}
});
saveSubject.onNext(true);
realm.close();
return saveSubject;
}
public Observable<Boolean> clearFavorites() {
Realm realm = Realm.getDefaultInstance();
realm.executeTransactionAsync(
transaction -> {
RealmResults<Translation> results = transaction
.where(Translation.class)
.equalTo("mInFavorites", true)
.findAll();
for (Translation result : results) {
result.setFavorites(false);
if (!result.isHistory()) {
result.deleteFromRealm();
}
}
},
() -> deleteSubject.onNext(true),
error -> deleteSubject.onError(error));
realm.close();
return deleteSubject;
}
public Observable<Boolean> clearHistory() {
Realm realm = Realm.getDefaultInstance();
realm.executeTransactionAsync(
transaction -> {
RealmResults<Translation> results = transaction
.where(Translation.class)
.equalTo("mInHistory", true)
.findAll();
for (Translation result : results) {
result.setHistory(false);
if (!result.isFavorites()) {
result.deleteFromRealm();
}
}
}, () -> deleteSubject.onNext(true),
error -> deleteSubject.onError(error));
realm.close();
return deleteSubject;
}
public List<Translation> getFavorites() {
return realmUI
.where(Translation.class)
.equalTo("mInFavorites", true)
.findAll();
}
public List<Translation> getHistory() {
return realmUI
.where(Translation.class)
.equalTo("mInHistory", true)
.findAll();
}
}
Листинг В.2 – Исходный код модуля “RepositoryImpl.java”
public class RepositoryImpl implements Repository {
@Inject
TranslateApi translateApi;
@Inject
DictionaryApi dictionaryApi;
@Inject
Mapper mMapper;
@Inject
RealmHelper realmHelper;
public RepositoryImpl(TranslateApi api, Mapper mapper) {
App.getDataComponent().inject(this);
translateApi = api;
mMapper = mapper;
}
/**
* If cache empty
* REST Call;
* write to Realm;
* read from Realm;
* Display;
* else
* REST Call;
* read cached form Realm;
* Display cached;
* get recent langs from call;
* update cache;
* Display recent;
* @param ui user interface language
* @return Observable
*/
@Override
public Observable<List<Language>> getSupportLanguages(String ui) {
List<Language> cachedLangs = realmHelper.readAllSupportLanguages();
Observable<List<Language>> observable = translateApi
.getSupportLanguages(Data.TRANSLATE_API_KEY, ui)
.subscribeOn(Schedulers.io())
.map(mMapper::transform)
.observeOn(Schedulers.computation())
.doOnNext(languages -> {
for (Language language: languages)
realmHelper.writeLanguageResponseToRealm(language);
})
.observeOn(AndroidSchedulers.mainThread())
.map(languages -> realmHelper.readAllSupportLanguages())
.onErrorReturn(throwable -> {
Log.d("tag_", "code: " + ((HttpException)throwable).code());
return cachedLangs;
});
if (cachedLangs != null){
Log.d("tag_", "cached rep: " + cachedLangs);
observable = Observable.mergeDelayError(observable, Observable.just(cachedLangs));
}
return observable;
}
private Observable<Translation> translateWithoutDict(String text, String lang) {
return translateApi
.translate(Data.TRANSLATE_API_KEY, text, lang)
.map(mMapper::transform);
}
@Override
public Observable<Translation> translate(String text, String lang, String ui) {
return Observable.zip(
translateWithoutDict(text, lang),
dictionaryApi
.getDictionary(Data.DICTIONARY_API_KEY, lang, text, ui)
.onErrorReturnItem(new DictionaryResponse()),
(translation, dictionaryResponse) -> {
if (translation != null && dictionaryResponse != null) {
translation.setDefList(dictionaryResponse.getDef());
}
Log.d("tag_", "OKK");
return translation;
})
.subscribeOn(Schedulers.io());
}
@Override
public Observable<Translation> translate(String text) {
return null;
}
@Override
public List<Translation> getHistory() {
return realmHelper.getHistory();
}
public List<Translation> getFavorites() {
return realmHelper.getFavorites();
}
@Override
public Observable<Boolean> saveTranslation(Translation translation) {
return realmHelper.writeTranslationToRealm(translation);
}
@Override
public Observable<Boolean> deleteHistory() {
return realmHelper.clearHistory();
}
@Override
public Observable<Boolean> deleteFavorites() {
return realmHelper.clearFavorites();
}
}
Листинг В.3 – Исходный код модуля “SupportLangsGetter.java”
public class SupportLangsGetter implements SupportLangsGetterInteractor {
@Inject
Repository mRepository;
@Inject
Mapper mapper;
public SupportLangsGetter(Repository repository) {
App.getDataComponent().inject(this);
this.mRepository = repository;
}
@Override
public Observable<List<Language>> getLanguages() {
return mRepository.getSupportLanguages("ru");
}
}
Листинг В.4 – Исходный код модуля “TranslationGetter.java”
public class TranslationGetter implements TranslationGetterInteractor {
@Inject
Repository repository;
@Inject
RealmHelper realmHelper;
private PublishSubject<Translation> translationSubject = PublishSubject.create();
private PublishSubject<Boolean> deleteSubject = PublishSubject.create();
private PublishSubject<Boolean> saveSubject = PublishSubject.create();
private PublishSubject<Boolean> checkedSubject = PublishSubject.create();
public TranslationGetter(Repository repository, RealmHelper realmHelper) {
this.repository = repository;
this.realmHelper = realmHelper;
}
private Observable<Translation> translate(String text, Language from, Language to) {
return repository.translate(text, from.getName() + "-" + to.getName(), "ru");
}
@Override
public Observable<Translation> translate(Translation translation) {
return translate(translation.getOriginalText(), translation.getFromLang(),
translation.getToLang())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(receivedTranslation -> {
receivedTranslation.setFromLang(translation.getFromLang());
receivedTranslation.setToLang(translation.getToLang());
receivedTranslation.setOriginalText(translation.getOriginalText());
})
.mergeWith(translationSubject);
}
@Override
public PublishSubject<Translation> getTranslationSetter() {
return translationSubject;
}
@Override
public List<Translation> getHistory() {
return repository.getHistory();
}
@Override
public List<Translation> getFavorites() {
return repository.getFavorites();
}
@Override
public void saveTranslation(Translation translation) {
repository
.saveTranslation(translation)
.subscribe(saveSubject::onNext, saveSubject::onError);
}
@Override
public void deleteHistory() {
repository
.deleteHistory()
.subscribe(deleteSubject::onNext, deleteSubject::onError);
}
@Override
public void deleteFavorites() {
repository
.deleteFavorites()
.subscribe(deleteSubject::onNext, deleteSubject::onError);
}
@Override
public void checkChanged() {
checkedSubject.onNext(true);
}
@Override
public Observable<Boolean> getDeleteObservable() {
return deleteSubject;
}
@Override
public Observable<Boolean> getSavedObservable() {
return saveSubject;
}
@Override
public Observable<Boolean> getCheckedObservable() {
return checkedSubject;
}
}
Листинг В.5 – Исходный код модуля “DictionaryApi.java”
public interface DictionaryApi {
@GET("lookup")
Observable<DictionaryResponse> getDictionary(@Query("key") String key,
@Query("lang") String lang,
@Query("text") String text,
@Query("ui") String ui);
}
Листинг В.5 – Исходный код модуля “TranslateApi.java”
public interface TranslateApi {
@GET("getLangs")
Observable<SupportLanguageResponse> getSupportLanguages(@Query("key") String key,
@Query("ui") String ui);
@GET("detect")
Observable<DetectLanguageResponse> detectLanguage(@Query("key") String key,
@Query("text") String text);
@GET("translate")
Observable<TranslationResponse> translate(@Query("key") String key,
@Query("text") String text,
@Query("lang") String lang);
@GET("translate")
Observable<TranslationResponse> translateWithLanguageDetect(@Query("key") String key,
@Query("text") String text,
@Query("options") int option);
}