1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.cooliris.picasa; 18 19 import org.xml.sax.Attributes; 20 21 /** 22 * This class models the photo entry kind in the Picasa GData API. 23 */ 24 @Entry.Table("photos") 25 public final class PhotoEntry extends Entry { 26 public static final EntrySchema SCHEMA = new EntrySchema(PhotoEntry.class); 27 28 /** 29 * The user account that is the sync source for this entry. Must be set 30 * before insert/update. 31 */ 32 @Column("sync_account") 33 public String syncAccount; 34 35 /** 36 * The "edit" URI of the photo. 37 */ 38 @Column("edit_uri") 39 public String editUri; 40 41 /** 42 * The containing album ID. 43 */ 44 @Column(value = "album_id", indexed = true) 45 public long albumId; 46 47 /** 48 * The display index of the photo within the album. Must be set before 49 * insert/update. 50 */ 51 @Column(value = "display_index", indexed = true) 52 public int displayIndex; 53 54 /** 55 * The title of the photo. 56 */ 57 @Column("title") 58 public String title; 59 60 /** 61 * A short summary of the photo. 62 */ 63 @Column("summary") 64 public String summary; 65 66 /** 67 * The date the photo was added. 68 */ 69 @Column("date_published") 70 public long datePublished; 71 72 /** 73 * The date the photo was last updated. 74 */ 75 @Column("date_updated") 76 public long dateUpdated; 77 78 /** 79 * The date the photo entry was last edited. May be more recent than 80 * dateUpdated. 81 */ 82 @Column("date_edited") 83 public long dateEdited; 84 85 /** 86 * The date the photo was captured as specified in the EXIF data. 87 */ 88 @Column("date_taken") 89 public long dateTaken; 90 91 /** 92 * The number of comments associated with the photo. 93 */ 94 @Column("comment_count") 95 public int commentCount; 96 97 /** 98 * The width of the photo in pixels. 99 */ 100 @Column("width") 101 public int width; 102 103 /** 104 * The height of the photo in pixels. 105 */ 106 @Column("height") 107 public int height; 108 109 /** 110 * The rotation of the photo in degrees, if rotation has not already been 111 * applied. 112 */ 113 @Column("rotation") 114 public int rotation; 115 116 /** 117 * The size of the photo is bytes. 118 */ 119 @Column("size") 120 public int size; 121 122 /** 123 * The latitude associated with the photo. 124 */ 125 @Column("latitude") 126 public double latitude; 127 128 /** 129 * The longitude associated with the photo. 130 */ 131 @Column("longitude") 132 public double longitude; 133 134 /** 135 * The "mini-thumbnail" URL for the photo (currently 144px-cropped). 136 */ 137 @Column("thumbnail_url") 138 public String thumbnailUrl; 139 140 /** 141 * The "screennail" URL for the photo (currently 800px). 142 */ 143 @Column("screennail_url") 144 public String screennailUrl; 145 146 /** 147 * The "content" URL for the photo (currently 1280px, or a video). The 148 * original image URL is not fetched since "imgmax" accepts one size, used 149 * to get this resource. 150 */ 151 @Column("content_url") 152 public String contentUrl; 153 154 /** 155 * The MIME type of the content URL. 156 */ 157 @Column("content_type") 158 public String contentType; 159 160 /** 161 * A link to the HTML page associated with the album. 162 */ 163 @Column("html_page_url") 164 public String htmlPageUrl; 165 166 /** 167 * Resets values to defaults for object reuse. 168 */ 169 @Override 170 public void clear() { 171 super.clear(); 172 syncAccount = null; 173 editUri = null; 174 albumId = 0; 175 displayIndex = 0; 176 title = null; 177 summary = null; 178 datePublished = 0; 179 dateUpdated = 0; 180 dateEdited = 0; 181 dateTaken = 0; 182 commentCount = 0; 183 width = 0; 184 height = 0; 185 rotation = 0; 186 size = 0; 187 latitude = 0; 188 longitude = 0; 189 thumbnailUrl = null; 190 screennailUrl = null; 191 contentUrl = null; 192 contentType = null; 193 htmlPageUrl = null; 194 } 195 196 /** 197 * Sets the property value corresponding to the given XML element, if 198 * applicable. 199 */ 200 @Override 201 public void setPropertyFromXml(String uri, String localName, Attributes attrs, String content) { 202 try { 203 char localNameChar = localName.charAt(0); 204 if (uri.equals(GDataParser.GPHOTO_NAMESPACE)) { 205 switch (localNameChar) { 206 case 'i': 207 if (localName.equals("id")) { 208 id = Long.parseLong(content); 209 } 210 break; 211 case 'a': 212 if (localName.equals("albumid")) { 213 albumId = Long.parseLong(content); 214 } 215 break; 216 case 't': 217 if (localName.equals("timestamp")) { 218 dateTaken = Long.parseLong(content); 219 } 220 break; 221 case 'c': 222 if (localName.equals("commentCount")) { 223 commentCount = Integer.parseInt(content); 224 } 225 break; 226 case 'w': 227 if (localName.equals("width")) { 228 width = Integer.parseInt(content); 229 } 230 break; 231 case 'h': 232 if (localName.equals("height")) { 233 height = Integer.parseInt(content); 234 } 235 break; 236 case 'r': 237 if (localName.equals("rotation")) { 238 rotation = Integer.parseInt(content); 239 } 240 break; 241 case 's': 242 if (localName.equals("size")) { 243 size = Integer.parseInt(content); 244 } 245 break; 246 case 'l': 247 if (localName.equals("latitude")) { 248 latitude = Double.parseDouble(content); 249 } else if (localName.equals("longitude")) { 250 longitude = Double.parseDouble(content); 251 } 252 break; 253 } 254 } else if (uri.equals(GDataParser.ATOM_NAMESPACE)) { 255 switch (localNameChar) { 256 case 't': 257 if (localName.equals("title")) { 258 title = content; 259 } 260 break; 261 case 's': 262 if (localName.equals("summary")) { 263 summary = content; 264 } 265 break; 266 case 'p': 267 if (localName.equals("published")) { 268 datePublished = GDataParser.parseAtomTimestamp(content); 269 } 270 break; 271 case 'u': 272 if (localName.equals("updated")) { 273 dateUpdated = GDataParser.parseAtomTimestamp(content); 274 } 275 break; 276 case 'l': 277 if (localName.equals("link")) { 278 String rel = attrs.getValue("", "rel"); 279 String href = attrs.getValue("", "href"); 280 if (rel.equals("alternate") && attrs.getValue("", "type").equals("text/html")) { 281 htmlPageUrl = href; 282 } else if (rel.equals("edit")) { 283 editUri = href; 284 } 285 } 286 break; 287 } 288 } else if (uri.equals(GDataParser.APP_NAMESPACE)) { 289 if (localName.equals("edited")) { 290 dateEdited = GDataParser.parseAtomTimestamp(content); 291 } 292 } else if (uri.equals(GDataParser.MEDIA_RSS_NAMESPACE)) { 293 if (localName.equals("thumbnail")) { 294 int width = Integer.parseInt(attrs.getValue("", "width")); 295 int height = Integer.parseInt(attrs.getValue("", "height")); 296 int dimension = Math.max(width, height); 297 String url = attrs.getValue("", "url"); 298 if (dimension <= 300) { 299 thumbnailUrl = url; 300 } else { 301 screennailUrl = url; 302 } 303 } else if (localName.equals("content")) { 304 // Only replace an existing URL if the MIME type is video. 305 String type = attrs.getValue("", "type"); 306 if (contentUrl == null || type.startsWith("video/")) { 307 contentUrl = attrs.getValue("", "url"); 308 contentType = type; 309 } 310 } 311 } else if (uri.equals(GDataParser.GML_NAMESPACE)) { 312 if (localName.equals("pos")) { 313 int spaceIndex = content.indexOf(' '); 314 if (spaceIndex != -1) { 315 latitude = Double.parseDouble(content.substring(0, spaceIndex)); 316 longitude = Double.parseDouble(content.substring(spaceIndex + 1)); 317 } 318 } 319 } 320 } catch (Exception e) { 321 return; 322 } 323 } 324 325 } 326