/* * Copyright 2012 GitHub Inc. * * 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 com.github.mobile.ui.repo; import static java.lang.String.CASE_INSENSITIVE_ORDER; import android.content.Context; import android.os.AsyncTask; import com.github.mobile.RequestReader; import com.github.mobile.RequestWriter; import java.io.File; import java.io.Serializable; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedHashSet; import org.eclipse.egit.github.core.Repository; import org.eclipse.egit.github.core.User; /** * Model class for the repositories recently selected under an organization */ public class RecentRepositories implements Comparator<Repository>, Serializable { /** * Number of repositories retained per organization */ public static final int MAX_SIZE = 5; private static final long serialVersionUID = 580345177644233739L; private static final int VERSION = 2; private static File getFile(final Context context, final User organization) { return new File(context.getFilesDir(), "recent-repos-" + organization.getId() + ".ser"); } private LinkedHashSet<Long> ids; private final File file; private int id; /** * Create a recent repositories cache for the given organization * * @param context * @param organization */ public RecentRepositories(final Context context, final User organization) { file = getFile(context, organization); id = organization.getId(); } private void load() { LinkedHashSet<Long> loaded = new RequestReader(file, VERSION).read(); if (loaded == null) loaded = new LinkedHashSet<Long>(); ids = loaded; trim(); } private void trim() { Iterator<Long> iterator = ids.iterator(); while (iterator.hasNext() && ids.size() > MAX_SIZE) { iterator.next(); iterator.remove(); } } /** * Add repository to recent list * * @param repo * @return this recent list */ public RecentRepositories add(final Repository repo) { return repo != null ? add(repo.getId()) : this; } /** * Add id to recent list * * @param id * @return this recent list */ public RecentRepositories add(final long id) { if (ids == null) load(); ids.remove(id); ids.add(id); trim(); return this; } /** * Remove repository from recent list * * @param repo * @return this recent list */ public RecentRepositories remove(final Repository repo) { return repo != null ? remove(repo.getId()) : this; } /** * Remove id from recent list * * @param id * @return this recent list */ public RecentRepositories remove(final long id) { if (ids == null) load(); ids.remove(id); return this; } /** * Persist recent list asynchronously on a background thread * * @return this recent list */ public RecentRepositories saveAsync() { if (ids != null) new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { save(); return null; } }.execute(); return this; } /** * Persist recent list * * @return this recent list */ public RecentRepositories save() { final LinkedHashSet<Long> save = ids; if (save != null) new RequestWriter(file, VERSION).write(save); return this; } /** * Is the given repository in the recent list? * * @param repository * @return true if in recent list, false otherwise */ public boolean contains(Repository repository) { return repository != null && contains(repository.getId()); } /** * Is the given repository id in the recent list * * @param id * @return true if in recent list, false otherwise */ public boolean contains(long id) { if (ids == null) load(); return ids.contains(id); } @Override public int compare(final Repository lhs, final Repository rhs) { final boolean lRecent = contains(lhs); final boolean rRecent = contains(rhs); if (lRecent && !rRecent) return -1; if (!lRecent && rRecent) return 1; final int order = CASE_INSENSITIVE_ORDER.compare(lhs.getName(), rhs.getName()); if (order == 0) if (id == lhs.getOwner().getId()) return -1; else if (id == rhs.getOwner().getId()) return 1; else return CASE_INSENSITIVE_ORDER.compare( lhs.getOwner().getLogin(), rhs.getOwner().getLogin()); else return order; } }