package com.jdroid.android.uri; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.jdroid.android.application.AbstractApplication; import com.jdroid.java.annotation.Internal; import com.jdroid.java.collections.Lists; import com.jdroid.java.exception.UnexpectedException; import com.jdroid.java.utils.LoggerUtils; import org.slf4j.Logger; import java.util.List; /** * Mapper which allows to navigate the application using a Uri. */ public class UriMapper { private static final Logger LOGGER = LoggerUtils.getLogger(UriMapper.class); private static final String HTTP_UNDEFINED = "http://undefined"; private List<UriWatcher> uriWatchers = Lists.newArrayList(); @Internal public Boolean handleUri(@NonNull Activity activity, Intent intent, @Nullable UriHandler uriHandler, Boolean onActivityCreation) { Uri uri = UriUtils.getUri(intent); if (uri != null && !uri.getScheme().equals("notification")) { notifyToUriWatchers(uri); if (uriHandler != null) { String referrerCategory = ReferrerUtils.getReferrerCategory(activity); if (referrerCategory == null) { referrerCategory = HTTP_UNDEFINED; ReferrerUtils.setReferrer(intent, referrerCategory); } try { if (uriHandler.matches(uri)) { LOGGER.debug(uriHandler.getClass().getSimpleName() + " matches the main intent: " + uri.toString()); Intent mainIntent = uriHandler.createMainIntent(activity, uri); handleIntent(mainIntent, activity, uri, referrerCategory, onActivityCreation); } else { uriHandler.logUriNotMatch(uri); handleDefaultIntent(activity, uriHandler, uri, referrerCategory, onActivityCreation); } } catch (Exception e) { AbstractApplication.get().getExceptionHandler().logHandledException(new UnexpectedException("Error matching: " + uri.toString(), e)); try { handleDefaultIntent(activity, uriHandler, uri, referrerCategory, onActivityCreation); } catch (Exception e2) { Intent homeIntent = new Intent(activity, AbstractApplication.get().getHomeActivityClass()); activity.finish(); activity.startActivity(homeIntent); } } return true; } else { AbstractApplication.get().getExceptionHandler().logHandledException(new UnexpectedException("No uriHandler defined for: " + uri.toString())); } } return false; } private void handleIntent(Intent intent, Activity activity, Uri uri, String referrerCategory, Boolean onActivityCreation) { if (intent != null) { ReferrerUtils.setReferrer(intent, referrerCategory); String className = intent.getComponent().getShortClassName(); int dot = className.lastIndexOf('.'); if (dot != -1) { className = className.substring(dot + 1); } AbstractApplication.get().getAnalyticsSender().trackUriOpened(className, referrerCategory); if (activity.getIntent().getComponent().equals(intent.getComponent())) { intent.setData(uri); activity.setIntent(intent); } else { if (onActivityCreation) { activity.finish(); } activity.startActivity(intent); } } else { AbstractApplication.get().getAnalyticsSender().trackUriOpened(activity.getClass().getSimpleName(), referrerCategory); } } private void handleDefaultIntent(Activity activity, UriHandler uriHandler, Uri uri, String referrerCategory, Boolean onActivityCreation) { Intent intent = uriHandler.createDefaultIntent(activity, uri); handleIntent(intent, activity, uri, referrerCategory, onActivityCreation); } private void notifyToUriWatchers(final Uri uri) { if (!Lists.isNullOrEmpty(uriWatchers)) { for (UriWatcher each : uriWatchers) { LOGGER.debug("Notifying opened Uri to " + each.getClass().getSimpleName()); try { each.onUriOpened(uri); } catch (Exception e) { AbstractApplication.get().getExceptionHandler().logHandledException(e); } } } } public void addUriWatcher(@NonNull UriWatcher uriWatcher) { this.uriWatchers.add(uriWatcher); } }