package api.http.google.picasa;
import api.KeyValuePair;
import api.http.HttpRequest;
import api.http.google.GoogleAPI;
import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class PicasaPhoto{
/**
* creates the metadata XML of Picasa Photo.
*
* @param title the title of Picasa Photo.
* @param description the description of Picasa Photo.
* @param keywords the keywords of Picasa Photo.
* @param lastModified the last modified of Picasa Photo.
* @param canComment can Picasa Album post the Photo.
* @param position the position of Picasa Photo.
* @return the metadata XML of Picasa Photo.
*/
public static String createPhotoXML(String title, String description, Date lastModified, String keywords, Boolean canComment, String position){
StringBuilder sbr = new StringBuilder();
sbr.append("<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:media=\"http://search.yahoo.com/mrss/\" xmlns:gphoto=\"http://schemas.google.com/photos/2007\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\">");
sbr.append(String.format("<title>%s</title>", title));
sbr.append(String.format("<summary>%s</summary>", description));
if (canComment != null){
sbr.append(String.format("<gphoto:commentingEnabled>%s</gphoto:commentingEnabled>", canComment));
}
sbr.append(String.format("<gphoto:timestamp>%s</gphoto:timestamp>", ((lastModified != null) ? lastModified.getTime() : System.currentTimeMillis())));
if (position != null){
sbr.append(String.format("<georss:where><gml:Point><gml:pos>%s</gml:pos></gml:Point></georss:where>", position));
}
if (keywords != null){
sbr.append(String.format("<media:group><media:keywords>$keywords</media:keywords></media:group>", keywords));
}
sbr.append("<category scheme=\"http://schemas.google.com/g/2005#kind\" term=\"http://schemas.google.com/photos/2007#photo\"></category>");
sbr.append("</entry>");
return sbr.toString();
}
private PicasaAlbum picasaAlbum;
private String title;
private String photoId;
private String description;
private Date lastModified;
private String keywords;
private boolean canComment;
private String position;
private int width;
private int height;
private int length;
private String mime;
private String head;
private URL webUrl;
private URL feedUrl;
private URL entryUrl;
private URL editUrl;
private URL mediaUrl;
/**
* returns the Picasa Album object which cantains this object.
*
* @return the Picasa Album object which cantains this object.
*/
public PicasaAlbum getPicasaAlbum(){
return picasaAlbum;
}
/**
* returns the title.
*
* @return the title.
*/
public String getTitle(){
return title;
}
/**
* returns the photo id.
*
* @return the photo id.
*/
public String getPhotoId(){
return photoId;
}
/**
* returns the description.
*
* @return the description.
*/
public String getDescription(){
return description;
}
/**
* returns the last modified.
*
* @return the last modified.
*/
public Date getLastModified(){
return lastModified;
}
/**
* returns the keywords.
*
* @return the keywords.
*/
public String getKeywords(){
return keywords;
}
/**
* returns can be comment or not.
*
* @return can be comment or not.
*/
public boolean getCanComment(){
return canComment;
}
/**
* returns the position.
*
* @return the position.
*/
public String getPosition(){
return position;
}
/**
* returns the width.
*
* @return the width.
*/
public int getWidth(){
return width;
}
/**
* returns the height.
*
* @return the height.
*/
public int getHeight(){
return height;
}
/**
* returns the length.
*
* @return the length.
*/
public int getLength(){
return length;
}
/**
* returns the mime type.
*
* @return the mime type.
*/
public String getMime(){
return mime;
}
/**
* returns the head.
*
* @return the head.
*/
public String getHead(){
return head;
}
/**
* returns the web url.
*
* @return the web url.
*/
public URL getWebUrl(){
return webUrl;
}
/**
* returns the feed url.
*
* @return the feed url.
*/
public URL getFeedUrl(){
return feedUrl;
}
/**
* returns the entry url.
*
* @return the entry url.
*/
public URL getEntryUrl(){
return entryUrl;
}
/**
* returns the edit url.
*
* @return the edit url.
*/
public URL getEditUrl(){
return editUrl;
}
/**
* returns the media url.
*
* @return the media url.
*/
public URL getMediaUrl(){
return mediaUrl;
}
PicasaPhoto(PicasaAlbum picasaAlbum, Element documentRoot){
this.picasaAlbum = picasaAlbum;
this.initial(documentRoot);
}
/**
* constructs this object with given user and album id.
*
* @param user Google user.
* @param albumId Picasa Album id.
* @param photoId Picasa Photo id.
* @param googleapi the Google API with exist auth token.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaPhoto(String user, String albumId, String photoId, GoogleAPI googleapi) throws IOException, ParserConfigurationException, SAXException{
PicasaWeb $picasaWeb = new PicasaWeb(user, googleapi);
PicasaAlbum $picasaAlbum = $picasaWeb.getAlbum(albumId);
PicasaPhoto $picasaPhoto = $picasaAlbum.getPhoto(photoId);
this.picasaAlbum = $picasaPhoto.picasaAlbum;
this.title = $picasaPhoto.title;
this.photoId = $picasaPhoto.photoId;
this.description = $picasaPhoto.description;
this.lastModified = $picasaPhoto.lastModified;
this.keywords = $picasaPhoto.keywords;
this.canComment = $picasaPhoto.canComment;
this.position = $picasaPhoto.position;
this.width = $picasaPhoto.width;
this.height = $picasaPhoto.height;
this.length = $picasaPhoto.length;
this.mime = $picasaPhoto.mime;
this.head = $picasaPhoto.head;
this.webUrl = $picasaPhoto.webUrl;
this.feedUrl = $picasaPhoto.feedUrl;
this.entryUrl = $picasaPhoto.entryUrl;
this.editUrl = $picasaPhoto.editUrl;
this.mediaUrl = $picasaPhoto.mediaUrl;
}
/**
* constructs this object with given user and album id.
*
* @param user Google user.
* @param albumId Picasa Album id.
* @param photoId Picasa Photo id.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaPhoto(String user, String albumId, String photoId) throws IOException, ParserConfigurationException, SAXException{
this(user, albumId, photoId, null);
}
private void initial(Element documentRoot){
try{
this.title = documentRoot.getElementsByTagName("title").item(0).getTextContent();
} catch (Exception ex){
}
try{
this.photoId = documentRoot.getElementsByTagName("gphoto:id").item(0).getTextContent();
} catch (Exception ex){
}
try{
this.description = documentRoot.getElementsByTagName("summary").item(0).getTextContent();
} catch (Exception ex){
}
try{
this.lastModified = new Date(Long.parseLong(documentRoot.getElementsByTagName("gphoto:timestamp").item(0).getTextContent()));
} catch (Exception ex){
}
try{
this.keywords = ((Element)documentRoot.getElementsByTagName("media:group").item(0)).getElementsByTagName("media:keywords").item(0).getTextContent();
} catch (Exception ex){
}
try{
this.canComment = Boolean.parseBoolean(documentRoot.getElementsByTagName("gphoto:commentingEnabled").item(0).getTextContent());
} catch (Exception ex){
}
try{
this.position = ((Element)((Element)documentRoot.getElementsByTagName("georss:where").item(0)).getElementsByTagName("gml:Point").item(0)).getElementsByTagName("gml:pos").item(0).getTextContent();
} catch (Exception ex){
}
try{
this.width = Integer.parseInt(documentRoot.getElementsByTagName("gphoto:width").item(0).getTextContent());
} catch (Exception ex){
}
try{
this.height = Integer.parseInt(documentRoot.getElementsByTagName("gphoto:height").item(0).getTextContent());
} catch (Exception ex){
}
try{
this.length = Integer.parseInt(documentRoot.getElementsByTagName("gphoto:size").item(0).getTextContent());
} catch (Exception ex){
}
try{
Node content = documentRoot.getElementsByTagName("content").item(0);
NamedNodeMap attributes = content.getAttributes();
this.mime = attributes.getNamedItem("type").getTextContent();
String src = attributes.getNamedItem("src").getTextContent();
int index = src.lastIndexOf('/');
this.head = src.substring(0, index);
} catch (Exception ex){
}
try{
NodeList links = documentRoot.getElementsByTagName("link");
for (int i = 0; i < links.getLength(); i++){
Node link = links.item(i);
if (link.getParentNode() == documentRoot){
try{
NamedNodeMap attributes = link.getAttributes();
String rel = attributes.getNamedItem("rel").getTextContent();
URL href = new URL(attributes.getNamedItem("href").getTextContent());
if (rel.equals("http://schemas.google.com/g/2005#feed")){
this.feedUrl = href;
} else if (rel.equals("self")){
this.entryUrl = href;
} else if (rel.equals("alternate")){
this.webUrl = href;
} else if (rel.equals("edit")){
this.editUrl = href;
} else if (rel.equals("edit-media")){
this.mediaUrl = href;
}
} catch (Exception ex){
}
}
}
} catch (Exception ex){
}
}
/**
* updates the Picasa Photo.
*
* @param title the title of Picasa Photo.
* @param description the description of Picasa Photo.
* @param lastModified the last modified of Picasa Photo.
* @param keywords the keywords of Picasa Photo.
* @param canComment can Picasa Album post the Photo.
* @param position the position of Picasa Photo.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
*/
public void update(String title, String description, Date lastModified, String keywords, Boolean canComment, String position) throws IOException{
HttpRequest httpRequest = new HttpRequest(this.editUrl);
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
if (title != null){
this.title = title;
}
if (description != null){
this.description = description;
}
if (lastModified != null){
this.lastModified = lastModified;
}
if (keywords != null){
this.keywords = keywords;
}
if (canComment != null){
this.canComment = canComment;
}
if (position != null){
this.position = position;
}
String data = PicasaPhoto.createPhotoXML(this.title, this.description, this.lastModified, this.keywords, this.canComment, this.position);
httpRequest.setData(data);
httpRequest.setMethod(HttpRequest.METHOD_PUT);
httpRequest.setContentType("application/atom+xml");
String response = httpRequest.send();
}
/**
* deleted the Picasa Photo.
*
* @throws IOException the url is not exist or something wrong of the server
* of target url.
*/
public void delete() throws IOException{
HttpRequest httpRequest = new HttpRequest(this.editUrl);
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
httpRequest.setMethod(HttpRequest.METHOD_DELETE);
httpRequest.setContentType("application/atom+xml");
String response = httpRequest.send();
this.title = null;
this.photoId = null;
this.description = null;
this.lastModified = null;
this.keywords = null;
this.canComment = false;
this.position = null;
this.width = 0;
this.height = 0;
this.length = 0;
this.mime = null;
this.head = null;
this.webUrl = null;
this.feedUrl = null;
this.entryUrl = null;
this.editUrl = null;
this.mediaUrl = null;
}
/**
* get a Picasa Comment object with given comment id.
*
* @param id comment id.
* @return a Picasa Comment object.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaComment getComment(String id) throws IOException, ParserConfigurationException, SAXException{
URL url = new URL(this.entryUrl.toString() + "/commentid/" + id);
return this.getComment(url);
}
private PicasaComment getComment(URL url) throws IOException, ParserConfigurationException, SAXException{
HttpRequest httpRequest = new HttpRequest(url);
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
String response = httpRequest.send();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(response)));
return new PicasaComment(this, document.getDocumentElement());
}
/**
* get an array of Picasa Comment objects.
*
* @return an array Picasa Comment objects.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaComment[] listComments() throws IOException, ParserConfigurationException, SAXException{
HttpRequest httpRequest = new HttpRequest(this.feedUrl);
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
String response = httpRequest.send();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(response)));
List<PicasaComment> picasaComments = new ArrayList<PicasaComment>();
NodeList entries = document.getElementsByTagName("entry");
for (int i = 0; i < entries.getLength(); i++){
Element entry = (Element)entries.item(i);
picasaComments.add(new PicasaComment(this, entry));
}
return picasaComments.toArray(new PicasaComment[picasaComments.size()]);
}
/**
* adds a comment to this Picasa Photo.
*
* @param comment comment string.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaComment addComment(String comment) throws IOException, ParserConfigurationException, SAXException{
HttpRequest httpRequest = new HttpRequest(this.feedUrl);
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
String data = PicasaComment.createCommentXML(comment);
httpRequest.setData(data);
httpRequest.setMethod(HttpRequest.METHOD_POST);
httpRequest.setContentType("application/atom+xml");
String response = httpRequest.send();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(response)));
return new PicasaComment(this, document.getDocumentElement());
}
/**
* get a Picasa Tag object with given tag string.
*
* @param tag tag string.
* @return a Picasa Tag object.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaTag getTag(String tag) throws IOException, ParserConfigurationException, SAXException{
URL url = new URL(this.entryUrl.toString() + "/tag/" + tag);
return this.getTag(url);
}
private PicasaTag getTag(URL url) throws IOException, ParserConfigurationException, SAXException{
HttpRequest httpRequest = new HttpRequest(url);
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
String response = httpRequest.send();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(response)));
return new PicasaTag(this, document.getDocumentElement());
}
/**
* get an array of Picasa Tag objects.
*
* @return an array Picasa Tag objects.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaTag[] listTags() throws IOException, ParserConfigurationException, SAXException{
String path = this.feedUrl.getQuery();
path = this.feedUrl.toString() + ((path == null || path.length() == 0) ? "?" : "&") + "kind=tag";
HttpRequest httpRequest = new HttpRequest(new URL(path));
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
String response = httpRequest.send();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(response)));
List<PicasaTag> picasaTags = new ArrayList<PicasaTag>();
NodeList entries = document.getElementsByTagName("entry");
for (int i = 0; i < entries.getLength(); i++){
Element entry = (Element)entries.item(i);
picasaTags.add(new PicasaTag(this, entry));
}
return picasaTags.toArray(new PicasaTag[picasaTags.size()]);
}
/**
* adds a tag to this Picasa Photo.
*
* @param tag tag string.
* @throws IOException the url is not exist or something wrong of the server
* of target url.
* @throws ParserConfigurationException the response is not a parsable XML.
* @throws SAXException the response is not a parsable XML.
*/
public PicasaTag addTag(String tag) throws IOException, ParserConfigurationException, SAXException{
HttpRequest httpRequest = new HttpRequest(this.feedUrl);
if (this.picasaAlbum.getPicasaWeb().getGoogleapi() != null){
KeyValuePair pair = this.picasaAlbum.getPicasaWeb().getGoogleapi().toAuthHeader();
httpRequest.addHeader(pair.key, pair.value);
}
String data = PicasaTag.createTagXML(tag);
httpRequest.setData(data);
httpRequest.setMethod(HttpRequest.METHOD_POST);
httpRequest.setContentType("application/atom+xml");
String response = httpRequest.send();
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(response)));
return new PicasaTag(this, document.getDocumentElement());
}
/**
* returns the string represent this object.
*
* @return the string represent this object.
*/
@Override
public String toString(){
StringBuilder sbr = new StringBuilder();
sbr.append(String.format("title = \"%s\"\n", this.title));
sbr.append(String.format("photo id = \"%s\"\n", this.photoId));
sbr.append(String.format("description = \"%s\"\n", this.description));
sbr.append(String.format("last modified = \"%s\"\n", ((this.lastModified == null) ? System.currentTimeMillis() : this.lastModified.getTime())));
sbr.append(String.format("keywords = \"%s\"\n", this.keywords));
sbr.append(String.format("can comment = \"%s\"\n", this.canComment));
sbr.append(String.format("position = \"%s\"\n", this.position));
sbr.append(String.format("width = \"%s\"\n", this.width));
sbr.append(String.format("height = \"%s\"\n", this.height));
sbr.append(String.format("length = \"%s\"\n", this.length));
sbr.append(String.format("mime = \"%s\"\n", this.mime));
sbr.append(String.format("head = \"%s\"\n", this.head));
sbr.append(String.format("feed url = \"%s\"\n", ((this.feedUrl == null) ? "" : this.feedUrl.toString())));
sbr.append(String.format("web url = \"%s\"\n", ((this.webUrl == null) ? "" : this.webUrl.toString())));
sbr.append(String.format("entry url = \"%s\"\n", ((this.entryUrl == null) ? "" : this.entryUrl.toString())));
sbr.append(String.format("edit url = \"%s\"\n", ((this.editUrl == null) ? "" : this.editUrl.toString())));
sbr.append(String.format("media url = \"%s\"\n", ((this.mediaUrl == null) ? "" : this.mediaUrl.toString())));
return sbr.toString();
}
}