-
-
Save jdkoren/32bc35c03df34d809145 to your computer and use it in GitHub Desktop.
UniversityProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.ContentProvider; | |
import android.content.ContentUris; | |
import android.content.ContentValues; | |
import android.content.UriMatcher; | |
import android.database.Cursor; | |
import android.net.Uri; | |
import android.provider.BaseColumns; | |
import android.text.TextUtils; | |
import com.example.squidbuni.UniversityDatabase; | |
import com.example.squidbuni.models.Course; | |
import com.example.squidbuni.models.FacultyMember; | |
import com.example.squidbuni.models.Student; | |
import com.example.squidbuni.provider.UniversityContract.Courses; | |
import com.example.squidbuni.provider.UniversityContract.Faculty; | |
import com.example.squidbuni.provider.UniversityContract.Students; | |
import com.example.squidbuni.provider.models.ContractStudent; | |
import com.example.squidbuni.provider.models.CoursesByStudent; | |
import com.example.squidbuni.provider.models.StudentsByCourse; | |
import com.yahoo.squidb.data.AbstractModel; | |
import com.yahoo.squidb.data.DatabaseDao; | |
import com.yahoo.squidb.data.SquidCursor; | |
import com.yahoo.squidb.data.TableModel; | |
import com.yahoo.squidb.sql.Criterion; | |
import com.yahoo.squidb.sql.Function; | |
import com.yahoo.squidb.sql.Query; | |
import com.yahoo.squidb.utility.ContentProviderQueryBuilder; | |
import com.yahoo.squidb.utility.ProjectionMap; | |
import java.util.List; | |
public class UniversityProvider extends ContentProvider { | |
// match codes | |
private static final int FACULTY = 100; | |
private static final int FACULTY_ID = 101; | |
private static final int FACULTY_ID_COURSES = 102; | |
private static final int STUDENTS = 200; | |
private static final int STUDENTS_ID = 201; | |
private static final int STUDENTS_ID_COURSES = 202; | |
private static final int COURSES = 300; | |
private static final int COURSES_ID = 301; | |
private static final int COURSES_ID_FACULTY = 302; | |
private static final int COURSES_ID_STUDENTS = 303; | |
private static final UriMatcher URI_MATCHER = buildUriMatcher(); | |
private static UriMatcher buildUriMatcher() { | |
final String authority = UniversityContract.AUTHORITY; | |
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); | |
matcher.addURI(authority, "faculty", FACULTY); | |
matcher.addURI(authority, "faculty/#", FACULTY_ID); | |
matcher.addURI(authority, "faculty/#/courses", FACULTY_ID_COURSES); | |
matcher.addURI(authority, "students", STUDENTS); | |
matcher.addURI(authority, "students/#", STUDENTS_ID); | |
matcher.addURI(authority, "students/#/courses", STUDENTS_ID_COURSES); | |
matcher.addURI(authority, "courses", COURSES); | |
matcher.addURI(authority, "courses/#", COURSES_ID); | |
matcher.addURI(authority, "courses/#/faculty", COURSES_ID_FACULTY); | |
matcher.addURI(authority, "courses/#/students", COURSES_ID_STUDENTS); | |
return matcher; | |
} | |
private DatabaseDao databaseDao; | |
private static final ProjectionMap FACULTY_PROJECTION_MAP = new ProjectionMap(); | |
private static final ProjectionMap COUNT_PROJECTION_MAP = new ProjectionMap(); | |
static { | |
FACULTY_PROJECTION_MAP.put(Faculty._ID, FacultyMember.ID); | |
FACULTY_PROJECTION_MAP.put(Faculty.NAME, FacultyMember.NAME); | |
FACULTY_PROJECTION_MAP.put(Faculty.DEPARTMENT, FacultyMember.DEPARTMENT); | |
COUNT_PROJECTION_MAP.put(BaseColumns._COUNT, Function.count()); | |
} | |
@Override | |
public boolean onCreate() { | |
databaseDao = new DatabaseDao(new UniversityDatabase(getContext())); | |
return true; | |
} | |
@Override | |
public String getType(Uri uri) { | |
switch (URI_MATCHER.match(uri)) { | |
case FACULTY: | |
return Faculty.CONTENT_TYPE; | |
case FACULTY_ID: | |
return Faculty.CONTENT_ITEM_TYPE; | |
case FACULTY_ID_COURSES: | |
return Courses.CONTENT_TYPE; | |
case STUDENTS: | |
return Students.CONTENT_TYPE; | |
case STUDENTS_ID: | |
return Students.CONTENT_ITEM_TYPE; | |
case STUDENTS_ID_COURSES: | |
return Courses.CONTENT_TYPE; | |
case COURSES: | |
return Courses.CONTENT_TYPE; | |
case COURSES_ID: | |
return Courses.CONTENT_ITEM_TYPE; | |
case COURSES_ID_FACULTY: | |
return Faculty.CONTENT_TYPE; | |
case COURSES_ID_STUDENTS: | |
return Students.CONTENT_TYPE; | |
} | |
throw new UnsupportedOperationException("Unknown uri: " + uri); | |
} | |
@Override | |
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { | |
Query query; | |
switch (URI_MATCHER.match(uri)) { | |
case FACULTY: | |
query = buildFacultyQuery(projection, selection, selectionArgs, sortOrder); | |
break; | |
case FACULTY_ID: | |
query = buildFacultyQuery(projection, selection, selectionArgs, sortOrder); | |
query.where(FacultyMember.ID.eq(ContentUris.parseId(uri))); | |
break; | |
case FACULTY_ID_COURSES: | |
query = buildCoursesQuery(projection, selection, selectionArgs, sortOrder); | |
query.where(Course.INSTRUCTOR_ID.eq(getIdPathSegment(uri, 1))); | |
break; | |
case STUDENTS: | |
query = buildStudentsQuery(projection, selection, selectionArgs, sortOrder); | |
break; | |
case STUDENTS_ID: | |
query = buildStudentsQuery(projection, selection, selectionArgs, sortOrder); | |
query.where(ContractStudent.ID.eq(ContentUris.parseId(uri))); | |
break; | |
case STUDENTS_ID_COURSES: | |
query = buildCoursesByStudentQuery(projection, selection, selectionArgs, sortOrder); | |
query.where(CoursesByStudent.STUDENT_ID.eq(getIdPathSegment(uri, 1))); | |
break; | |
case COURSES: | |
query = buildCoursesQuery(projection, selection, selectionArgs, sortOrder); | |
break; | |
case COURSES_ID: | |
query = buildCoursesQuery(projection, selection, selectionArgs, sortOrder); | |
query.where(Course.ID.eq(ContentUris.parseId(uri))); | |
break; | |
case COURSES_ID_FACULTY: | |
query = buildFacultyQuery(projection, selection, selectionArgs, sortOrder); | |
query.where(FacultyMember.ID.eq(getIdPathSegment(uri, 1))); | |
break; | |
case COURSES_ID_STUDENTS: | |
query = buildStudentsByCourseQuery(projection, selection, selectionArgs, sortOrder); | |
query.where(StudentsByCourse.COURSE_ID.eq(getIdPathSegment(uri, 1))); | |
break; | |
default: | |
throw new UnsupportedOperationException("Unsupported uri: " + uri); | |
} | |
query.limit(getLimit(uri)); | |
SquidCursor<AbstractModel> cursor = databaseDao.query(AbstractModel.class, query); | |
return cursor; | |
} | |
private long getIdPathSegment(Uri uri, int pathIndex) { | |
if (pathIndex < 0) { | |
throw new IllegalArgumentException("pathIndex can't be less than zero"); | |
} | |
List<String> pathSegments = uri.getPathSegments(); | |
if (pathSegments.size() <= pathIndex) { | |
throw new IllegalArgumentException("Uri has too few path segments"); | |
} | |
return Long.parseLong(pathSegments.get(pathIndex)); | |
} | |
private int getLimit(Uri uri) { | |
int limit = Query.NO_LIMIT; | |
String paramString = uri.getQueryParameter(UniversityContract.QUERY_PARAM_LIMIT); | |
if (!TextUtils.isEmpty(paramString)) { | |
try { | |
limit = Integer.parseInt(paramString); | |
} catch (NumberFormatException e) { | |
// ignore and return default | |
} | |
} | |
return limit; | |
} | |
private boolean isCountProjection(String[] projection) { | |
return projection != null && projection.length == 1 && BaseColumns._COUNT.equals(projection[0]); | |
} | |
private Query buildFacultyQuery(String[] projection, String selection, String[] selectionArgs, String sortOrder) { | |
ProjectionMap map = isCountProjection(projection) ? COUNT_PROJECTION_MAP : FACULTY_PROJECTION_MAP; | |
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder() | |
.setStrict(true) | |
.setProjectionMap(map) | |
.setDataSource(FacultyMember.TABLE) | |
.setDefaultOrder(FacultyMember.NAME.asc()); | |
return builder.build(projection, selection, selectionArgs, sortOrder); | |
} | |
private Query buildStudentsQuery(String[] projection, String selection, String[] selectionArgs, String sortOrder) { | |
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(ContractStudent.class) | |
.setStrict(true) | |
.setDefaultOrder(ContractStudent.NAME.asc()); | |
if (isCountProjection(projection)) { | |
builder.setProjectionMap(COUNT_PROJECTION_MAP); | |
} | |
return builder.build(projection, selection, selectionArgs, sortOrder); | |
} | |
private Query buildCoursesQuery(String[] projection, String selection, String[] selectionArgs, String sortOrder) { | |
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(Course.class) | |
.setStrict(true); | |
if (isCountProjection(projection)) { | |
builder.setProjectionMap(COUNT_PROJECTION_MAP); | |
} | |
return builder.build(projection, selection, selectionArgs, sortOrder); | |
} | |
private Query buildStudentsByCourseQuery(String[] projection, String selection, | |
String[] selectionArgs, String sortOrder) { | |
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(StudentsByCourse.class) | |
.setStrict(true); | |
if (isCountProjection(projection)) { | |
builder.setProjectionMap(COUNT_PROJECTION_MAP); | |
} | |
return builder.build(projection, selection, selectionArgs, sortOrder); | |
} | |
private Query buildCoursesByStudentQuery(String[] projection, String selection, String[] selectionArgs, | |
String sortOrder) { | |
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(CoursesByStudent.class) | |
.setStrict(true); | |
if (isCountProjection(projection)) { | |
builder.setProjectionMap(COUNT_PROJECTION_MAP); | |
} | |
return builder.build(projection, selection, selectionArgs, sortOrder); | |
} | |
@Override | |
public Uri insert(Uri uri, ContentValues values) { | |
TableModel model; | |
switch (URI_MATCHER.match(uri)) { | |
case FACULTY: | |
model = facultyMemberFromValues(values); | |
break; | |
case STUDENTS: | |
ContractStudent contractStudent = new ContractStudent(values); | |
model = contractStudent.mapToModel(new Student()); | |
break; | |
case COURSES: | |
model = courseFromValues(values); | |
break; | |
default: | |
throw new UnsupportedOperationException("Unsupported uri: " + uri); | |
} | |
if (databaseDao.createNew(model)) { | |
Uri newUri = ContentUris.withAppendedId(uri, model.getId()); | |
getContext().getContentResolver().notifyChange(newUri, null); | |
return newUri; | |
} | |
return null; | |
} | |
private FacultyMember facultyMemberFromValues(ContentValues values) { | |
FacultyMember faculty = new FacultyMember(); | |
faculty.setName(values.getAsString(Faculty.NAME)); | |
faculty.setDepartment(values.getAsString(Faculty.DEPARTMENT)); | |
return faculty; | |
} | |
private Course courseFromValues(ContentValues values) { | |
Course course = new Course(); | |
course.setCode(values.getAsString(Courses.CODE)); | |
course.setCredits(values.getAsInteger(Courses.CREDITS)); | |
course.setInstructorId(values.getAsLong(Courses.INSTRUCTOR_ID)); | |
course.setStartDate(values.getAsLong(Courses.START_DATE)); | |
course.setEndDate(values.getAsLong(Courses.END_DATE)); | |
return course; | |
} | |
@Override | |
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { | |
values.remove(BaseColumns._ID); | |
int numUpdated; | |
switch (URI_MATCHER.match(uri)) { | |
case FACULTY: { | |
FacultyMember template = facultyMemberFromValues(values); | |
numUpdated = databaseDao.update(Criterion.fromRawSelection(selection, selectionArgs), template); | |
break; | |
} | |
case FACULTY_ID: { | |
FacultyMember faculty = facultyMemberFromValues(values); | |
faculty.setId(ContentUris.parseId(uri)); | |
numUpdated = databaseDao.saveExisting(faculty) ? 1 : 0; | |
break; | |
} | |
case STUDENTS: { | |
ContractStudent contractStudent = new ContractStudent(values); | |
Student template = contractStudent.mapToModel(new Student()); | |
Query query = Query.select(ContractStudent.ID) | |
.from(ContractStudent.VIEW) | |
.where(Criterion.fromRawSelection(selection, selectionArgs)); | |
numUpdated = databaseDao.update(Student.ID.in(query), template); | |
break; | |
} | |
case STUDENTS_ID: { | |
ContractStudent contractStudent = new ContractStudent(values); | |
Student student = contractStudent.mapToModel(new Student()); | |
student.setId(ContentUris.parseId(uri)); | |
numUpdated = databaseDao.saveExisting(student) ? 1 : 0; | |
break; | |
} | |
case COURSES: { | |
Course template = courseFromValues(values); | |
numUpdated = databaseDao.update(Criterion.fromRawSelection(selection, selectionArgs), template); | |
break; | |
} | |
case COURSES_ID: { | |
Course course = courseFromValues(values); | |
course.setId(ContentUris.parseId(uri)); | |
numUpdated = databaseDao.saveExisting(course) ? 1 : 0; | |
break; | |
} | |
default: | |
throw new UnsupportedOperationException("Unsupported uri: " + uri); | |
} | |
if (numUpdated > 0) { | |
getContext().getContentResolver().notifyChange(uri, null); | |
} | |
return numUpdated; | |
} | |
@Override | |
public int delete(Uri uri, String selection, String[] selectionArgs) { | |
int numDeleted; | |
switch (URI_MATCHER.match(uri)) { | |
case FACULTY: { | |
numDeleted = databaseDao.deleteWhere(FacultyMember.class, | |
Criterion.fromRawSelection(selection, selectionArgs)); | |
break; | |
} | |
case FACULTY_ID: { | |
long id = ContentUris.parseId(uri); | |
numDeleted = databaseDao.delete(FacultyMember.class, id) ? 1 : 0; | |
break; | |
} | |
case STUDENTS: { | |
Query query = Query.select(ContractStudent.ID) | |
.from(ContractStudent.VIEW) | |
.where(Criterion.fromRawSelection(selection, selectionArgs)); | |
numDeleted = databaseDao.deleteWhere(Student.class, Student.ID.in(query)); | |
break; | |
} | |
case STUDENTS_ID: { | |
long id = ContentUris.parseId(uri); | |
numDeleted = databaseDao.delete(Student.class, id) ? 1 : 0; | |
break; | |
} | |
case COURSES: { | |
numDeleted = databaseDao.deleteWhere(Course.class, | |
Criterion.fromRawSelection(selection, selectionArgs)); | |
break; | |
} | |
case COURSES_ID: { | |
long id = ContentUris.parseId(uri); | |
numDeleted = databaseDao.delete(Course.class, id) ? 1 : 0; | |
break; | |
} | |
default: | |
throw new UnsupportedOperationException("Unsupported uri: " + uri); | |
} | |
if (numDeleted > 0) { | |
getContext().getContentResolver().notifyChange(uri, null); | |
} | |
return numDeleted; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment