package com.xda.one.ui.helper; import com.xda.one.api.inteface.PostClient; import com.xda.one.api.misc.Consumer; import com.xda.one.api.model.interfaces.Forum; import com.xda.one.api.model.response.container.ResponsePostContainer; import com.xda.one.api.retrofit.RetrofitPostClient; import com.xda.one.db.ForumDbHelper; import com.xda.one.model.augmented.AugmentedUnifiedThread; import com.xda.one.ui.ForumFragment; import com.xda.one.ui.MessagePagerFragment; import com.xda.one.ui.ThreadFragment; import com.xda.one.ui.UserProfileActivity; import com.xda.one.util.FragmentUtils; import com.xda.one.util.Utils; import android.content.Context; import android.net.Uri; import android.support.v4.app.Fragment; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import retrofit.Callback; import retrofit.RetrofitError; import retrofit.client.Response; public class UrlParseHelper { private static final Pattern PAGE_PATTERN = Pattern.compile("page(\\d+)"); private static final Pattern THREAD_PATTERN = Pattern.compile("-t(\\d+)"); public static void parseUrl(final Context context, final Uri uri, final Consumer<Fragment> success, final Runnable failure) { final String path = uri.getPath(); switch (path) { case "/showthread.php": parseThreadUrl(context, uri, success, failure); break; case "/private.php": parsePrivateUrl(success); break; case "/member.php": parseMemberUrl(context, uri, success); break; default: parsePossibleForumThreadPath(context, uri, success, failure); break; } } private static void parseMemberUrl(final Context context, final Uri uri, final Consumer<Fragment> success) { final String userId = uri.getQueryParameter("u"); success.run(null); context.startActivity(UserProfileActivity.createIntent(context, userId)); } private static void parsePossibleForumThreadPath(final Context context, final Uri uri, final Consumer<Fragment> success, final Runnable failure) { final List<String> segments = uri.getPathSegments(); if (Utils.isCollectionEmpty(segments)) { failure.run(); return; } // First we check if the last segment matches a page final String lastSegment = segments.get(segments.size() - 1); final Matcher pageMatcher = PAGE_PATTERN.matcher(lastSegment); if (pageMatcher.matches()) { // If it matches a page, the end of the penultimate segment should contain the threadId final String penultimateSegment = segments.get(segments.size() - 2); final Matcher threadIdMatcher = THREAD_PATTERN.matcher(penultimateSegment); if (threadIdMatcher.find()) { // So we found the threadId - look up the thread and switch to it final String threadId = threadIdMatcher.group(1); final int threadPage = Integer.parseInt(pageMatcher.group(1)); getPostFeed(context, success, failure, threadId, threadPage); } else { // If we have a page but not a thread, it's bad news failure.run(); } return; } // Now we try to see if we can match the last segment to a threadId directly without a page final Matcher threadIdMatcher = THREAD_PATTERN.matcher(lastSegment); if (threadIdMatcher.find()) { // Since we found it, we can go ahead and load the thread final String threadId = threadIdMatcher.group(1); getPostFeed(context, success, failure, threadId, 1); return; } // The only other case we need to deal with the forum path case // TODO - there are more possibilities which are ignored final ForumDbHelper helper = ForumDbHelper.getInstance(context); Forum parent = null; Forum forum = null; int parentId = -1; for (final String segment : segments) { parent = forum; forum = helper.searchSlug(parentId, segment); if (forum == null) { // Fail if the forum is null at any point failure.run(); return; } parentId = forum.getForumId(); } if (forum == null) { failure.run(); } else { if (forum.hasChildren()) { final ForumFragment instance = ForumFragment.createInstance(forum, null, new ArrayList<String>()); success.run(instance); } else { final String parentTitle = parent == null ? null : parent.getTitle(); final ThreadFragment instance = ThreadFragment .createDefault(forum.getForumId(), forum.getTitle(), parentTitle, new ArrayList<String>()); success.run(instance); } } } private static void parsePrivateUrl(final Consumer<Fragment> success) { success.run(new MessagePagerFragment()); } private static void parseThreadUrl(final Context context, final Uri uri, final Consumer<Fragment> success, final Runnable failure) { final String threadId = uri.getQueryParameter("t"); final String pageString = uri.getQueryParameter("page"); final int page = pageString == null ? 1 : Integer.parseInt(pageString); getPostFeed(context, success, failure, threadId, page); } private static void getPostFeed(final Context context, final Consumer<Fragment> success, final Runnable failure, final String threadId, final int page) { final PostClient userClient = RetrofitPostClient.getClient(context); userClient.getPostsAsync(threadId, page, new Callback<ResponsePostContainer>() { @Override public void success(final ResponsePostContainer container, final Response response) { final AugmentedUnifiedThread thread = new AugmentedUnifiedThread(container .getThread(), context); Fragment fragment = FragmentUtils.switchToPostList(thread, new ArrayList<String>(), container); success.run(fragment); } @Override public void failure(final RetrofitError error) { failure.run(); } }); } }