/*
* Copyright (C) 2007-2008 OpenIntents.org
*
* 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 org.openintents.provider;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;
/**
* Definition for content provider related to tag.
*/
public class Tag {
public static final class Tags implements BaseColumns {
/**
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI = Uri
.parse("content://org.openintents.tags/tags");
/**
* The default sort order for this table.
*/
public static final String DEFAULT_SORT_ORDER = "modified DESC";
/**
* The id of the tag.
* <p/>
* Type: STRING
* </P>
*/
public static final String TAG_ID = "tag_id";
/**
* The id of the content.
* <p/>
* Type: STRING
* </P>
*/
public static final String CONTENT_ID = "content_id";
/**
* The timestamp for when the tag was created.
* <p/>
* Type: INTEGER (long)
* </P>
*/
public static final String CREATED_DATE = "created";
/**
* The timestamp for when the tag was last modified.
* <p/>
* Type: INTEGER (long)
* </P>
*/
public static final String MODIFIED_DATE = "modified";
/**
* The timestamp for when the tag was last modified.
* <p/>
* Type: INTEGER (long)
* </P>
*/
public static final String ACCESS_DATE = "accessed";
/**
* First URI of the relationship (usually the tag).
*/
public static final String URI_1 = "uri_1";
/**
* Second URI of the relationship (usually the content).
*/
public static final String URI_2 = "uri_2";
/**
* The Uri to be tagged that the query is about.
*/
public static final String QUERY_URI = "uri";
/**
* The tag that the query is about.
*/
public static final String QUERY_TAG = "tag";
public static final String DISTINCT = "distinct";
public static final String QUERY_UNIQUE_TAG = "unique";
}
public static final class Contents implements BaseColumns {
/**
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI = Uri
.parse("content://org.openintents.tags/contents");
/**
* The default sort order for this table.
*/
public static final String DEFAULT_SORT_ORDER = "type DESC, uri";
/**
* The uri of the content, or the tag text if the uri starts with "TAG".
* This can be tested in SQL using "WHERE type like 'TAG%'".
* <p/>
* Type: TEXT
* </P>
*/
public static final String URI = "uri";
/**
* The type of the content, e.g TAG null means CONTENT.
* <p/>
* Type: TEXT
* </P>
*/
public static final String TYPE = "type";
/**
* The timestamp for when the note was created.
* <p/>
* Type: INTEGER (long)
* </P>
*/
public static final String CREATED_DATE = "created";
public static final String QUERY_BY_TYPE = "byType";
}
private static final String TAG = "Tag.java";
private static final String DELETE_URI = "tag.content_id = (select content2._id FROM content content2 WHERE content2.uri = ?)";
private static final String DELETE_TAG_URI = "tag.tag_id = (select content1._id FROM content content1 WHERE content1.uri = ?) "
+ "AND tag.content_id = (select content2._id FROM content content2 WHERE content2.uri = ?)";
private Context mContext;
public Tag(Context context) {
mContext = context;
}
public void removeTag(String tag, String uri) {
mContext.getContentResolver().delete(Tags.CONTENT_URI,
Tag.DELETE_TAG_URI, new String[]{tag, uri});
}
public void removeAllTags(String uri) {
mContext.getContentResolver().delete(Tags.CONTENT_URI, Tag.DELETE_URI,
new String[]{uri});
}
public void insertTag(String tag, String content) {
ContentValues values = new ContentValues(2);
values.put(Tags.URI_1, tag);
values.put(Tags.URI_2, content);
try {
mContext.getContentResolver().insert(Tags.CONTENT_URI, values);
} catch (Exception e) {
Log.i(TAG, "insert failed", e);
}
}
public void insertUniqueTag(String tag, String content) {
ContentValues values = new ContentValues(2);
values.put(Tags.URI_1, tag);
values.put(Tags.URI_2, content);
try {
Uri uri = Tags.CONTENT_URI.buildUpon()
.appendQueryParameter(Tags.QUERY_UNIQUE_TAG, "true")
.build();
mContext.getContentResolver().insert(uri, values);
} catch (Exception e) {
Log.i(TAG, "insert failed", e);
}
}
/**
* cursor over contentUriStrings is returned where the content is tagged
* with the given tag.
*
* @param tag
* @param contentUri
* @return
* @deprecated !! WARNING !! Cursor has to be closed by caller. Alternative
* API desired.
*/
public Cursor findTaggedContent(String tag, String contentUri) {
return mContext.getContentResolver().query(Tags.CONTENT_URI,
new String[]{Tags._ID, Tags.URI_2},
"content1.uri like ? and content2.uri like ?",
new String[]{tag, contentUri + "%"}, "content2.uri");
}
/**
* cursor over tags with all tags for the given content is returned.
*
* @param tag
* @param contentUri
* @return
* @deprecated !! WARNING !! Cursor has to be closed by caller. Alternative
* API desired.
*/
public Cursor findTags(String contentUri) {
return mContext.getContentResolver().query(Tags.CONTENT_URI,
new String[]{Tags._ID, Tags.URI_1}, "content2.uri = ?",
new String[]{contentUri}, "content1.uri");
}
public String findTags(String uri, String separator) {
Cursor tags = findTags(uri);
StringBuffer sb = new StringBuffer();
int colIndex = tags.getColumnIndex(Tags.URI_1);
while (tags.moveToNext()) {
sb.append(tags.getString(colIndex));
sb.append(separator);
}
if (sb.length() > 0) {
sb.deleteCharAt(sb.length() - separator.length());
}
tags.close();
return sb.toString();
}
/**
* cursor over tags with all tags for the given content is returned.
*
* @param contentUriPrefix
* @return
* @deprecated !! WARNING !! Cursor has to be closed by caller. Alternative
* API desired.
*/
public Cursor findTagsForContentType(String contentUriPrefix) {
Uri uri = Contents.CONTENT_URI.buildUpon()
.appendQueryParameter(Tags.DISTINCT, "true").build();
return mContext
.getContentResolver()
.query(uri,
new String[]{Contents._ID, Contents.URI},
"exists(select * from content content2, tag tag where content2.uri like ? and content2._id = tag.content_id and content._id = tag.tag_id)",
new String[]{contentUriPrefix + "%"}, "content.uri");
}
/**
* Get a cursor with all tags
*
* @return
* @deprecated !! WARNING !! Cursor has to be closed by caller. Alternative
* API desired.
*/
public Cursor findAllTags() {
return mContext.getContentResolver().query(Contents.CONTENT_URI,
new String[]{Contents._ID, Contents.URI, Contents.TYPE},
"type like 'TAG%'", null, Contents.DEFAULT_SORT_ORDER);
}
/**
* Get a cursor with all used tags, i.e. at least one content has been
* tagged with this tag.
*
* @return
* @deprecated !! WARNING !! Cursor has to be closed by caller. Alternative
* API desired.
*/
public Cursor findAllUsedTags() {
return mContext
.getContentResolver()
.query(Contents.CONTENT_URI,
new String[]{Contents._ID, Contents.URI,
Contents.TYPE},
"type like 'TAG%' and (select count(*) from tag where tag.tag_id = content._id) > 0",
null, Contents.DEFAULT_SORT_ORDER
);
}
/**
* start add tag activity. Only useful, if tag or uri is null. Consider
* using insertTag if you want to add the tag without user interaction.
*
* @param tag
* @param uri
*/
public void startAddTagActivity(String tag, String uri) {
Intent intent = new Intent(org.openintents.OpenIntents.TAG_ACTION,
Tags.CONTENT_URI).putExtra(Tags.QUERY_TAG, tag).putExtra(
Tags.QUERY_URI, uri);
mContext.startActivity(intent);
}
}