package com.novoda.priorityshare.composer; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; /** * A {@link com.novoda.priorityshare.composer.MessageComposer} that enforces a * maximum composed text length. * <p/> * This class assumes URLs will <i>NOT</i> be shortened. If a different behaviour * is required, users can subclass and override {@link #getShortenedUrlLengthFor(String)} * to provide any custom shortened URL length calculation logic. Please note that * this class <i>NOT</i> perform the shortening itself, as this is usually done by * the sharing targets themselves when submitting the post. It will only do the * length limiting based on the final, shortened URL length. * <p/> * The composed text will have the following format: * <code>[prefix] [subject] [url] [suffix]</code> * Where the <code>[subject]</code> field will be ellipsized as needed to fit any * characters allowance left from the other fields. */ public class MaxLengthMessageComposer implements MessageComposer { private String suffix; private String prefix; private int maxLength; public MaxLengthMessageComposer(int maxLength) { this.maxLength = maxLength; } public MaxLengthMessageComposer setSuffix(String suffix) { this.suffix = safeTrim(suffix); return this; } public MaxLengthMessageComposer setPrefix(String prefix) { this.prefix = safeTrim(prefix); return this; } private static String safeTrim(String text) { return text != null ? text.trim() : ""; } @Override public Bundle composeToBundle(String subject, String url) { Bundle bundle = new Bundle(); bundle.putString(Intent.EXTRA_TEXT, composeText(subject, url)); return bundle; } private String composeText(String subject, String url) { int availableLength = maxLength; StringBuilder stringBuilder = new StringBuilder(maxLength); int prefixAndSuffixLength = computeAppendedLengthIncludingSeparatorSpaces(prefix, suffix); int urlLength = computeUrlLengthIncludingSeparatorSpace(url); availableLength -= prefixAndSuffixLength; availableLength -= urlLength; appendWithTrailingSpaceIfNotNullOrEmpty(prefix, stringBuilder); String trimmedSubject = ellipsizeTextIfExceedsMaxLength(subject, availableLength); appendWithTrailingSpaceIfNotNullOrEmpty(trimmedSubject, stringBuilder); appendWithTrailingSpaceIfNotNullOrEmpty(url, stringBuilder); appendWithTrailingSpaceIfNotNullOrEmpty(suffix, stringBuilder); return stringBuilder.toString().trim(); } private int computeUrlLengthIncludingSeparatorSpace(String uri) { if (TextUtils.isEmpty(uri)) { return 0; } return getShortenedUrlLengthFor(uri) + 1; } protected int getShortenedUrlLengthFor(String uri) { return uri.length(); } private int computeAppendedLengthIncludingSeparatorSpaces(String... stringsToAppend) { int length = 0; for (String string : stringsToAppend) { if (!TextUtils.isEmpty(string)) { length += string.length() + 1; } } return length; } private void appendWithTrailingSpaceIfNotNullOrEmpty(String string, StringBuilder stringBuilder) { if (!TextUtils.isEmpty(string)) { stringBuilder.append(string).append(" "); } } private String ellipsizeTextIfExceedsMaxLength(String text, int maxLength) { if (TextUtils.isEmpty(text)) { return null; } if (text.length() > maxLength) { text = text.substring(0, maxLength - 1) + "…"; } return text; } }