/* Copyright (c) 2006 Google 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 sample.gbase.recipe; import com.google.api.gbase.client.GoogleBaseEntry; import com.google.api.gbase.client.NumberUnit; import com.google.gdata.data.Content; import com.google.gdata.data.DateTime; import com.google.gdata.data.OtherContent; import com.google.gdata.data.Person; import com.google.gdata.data.TextConstruct; import com.google.gdata.data.TextContent; import java.net.MalformedURLException; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; /** * One recipe, ready to be displayed. * Just a data holding object. */ public class Recipe { public final static String RECIPE_ITEMTYPE = "recipes"; public final static String MAIN_INGREDIENT_ATTRIBUTE = "main ingredient"; public final static String CUISINE_ATTRIBUTE = "cuisine"; public final static String COOKING_TIME_ATTRIBUTE = "cooking time"; public final static String AUTHOR_UNKNOWN = ""; private final String id; private final DateTime postedOn; private final String postedBy; private final NumberUnit<Integer> cookingTime; private final String url; private final String title; private final String description; /** A never-null list that contains the main ingredients. */ private final Set<String> mainIngredient; /** A never-null list that contains the cuisines. */ private final Set<String> cuisine; /** * Creates a recipe. The parameters can be null. * * @param id id generated by the GoogleBase server * @param title * @param url alternate url of the recipe; * if null, when the recipe is used to insert or to update * it is generated by the GoogleBase server * @param description * @param mainIngredient * @param cuisine * @param cookingTime */ public Recipe(String id, String title, String url, String description, Set<String> mainIngredient, Set<String> cuisine, NumberUnit<Integer> cookingTime) { if (mainIngredient == null) { mainIngredient = new HashSet<String>(); } if (cuisine == null) { cuisine = new HashSet<String>(); } this.id = id; this.title = title; this.url = url; this.description = description; this.mainIngredient = mainIngredient; this.cuisine = cuisine; this.cookingTime = cookingTime; this.postedOn = null; this.postedBy = null; } /** * Creates a recipe out of a GoogleBaseEntry. * * @param entry an entry that represents a recipe */ public Recipe(GoogleBaseEntry entry) { id = extractIdFromUrl(entry.getId()); title = entry.getTitle().getPlainText(); url = entry.getHtmlLink().getHref(); String description = null; if (entry.getContent() != null) { Content content = entry.getContent(); if (content instanceof TextContent) { description = ((TextContent)content).getContent().getPlainText(); } else if (content instanceof OtherContent) { description = ((OtherContent)content).getText(); } } this.description = description; mainIngredient = new HashSet<String>(entry.getGoogleBaseAttributes(). getTextAttributeValues(MAIN_INGREDIENT_ATTRIBUTE)); cuisine = new HashSet<String>(entry.getGoogleBaseAttributes(). getTextAttributeValues(CUISINE_ATTRIBUTE)); cookingTime = entry.getGoogleBaseAttributes(). getIntUnitAttribute(COOKING_TIME_ATTRIBUTE); postedOn = entry.getPublished(); // if an entry has no author specified, will set it to empty string List<Person> authors = entry.getAuthors(); postedBy = (authors.isEmpty() ? AUTHOR_UNKNOWN : authors.get(0).getName()); } /** * Creates an empty recipe, the values are null or empty Sets. */ public Recipe() { this(null, null, null, null, null, null, null); } public GoogleBaseEntry toGoogleBaseEntry(String idUrl) { GoogleBaseEntry entry = new GoogleBaseEntry(); entry.getGoogleBaseAttributes().setItemType(RECIPE_ITEMTYPE); if (idUrl != null) { entry.setId(idUrl); } entry.setTitle(TextConstruct.create(TextConstruct.Type.TEXT, title, null)); if (url != null) { entry.addHtmlLink(url, null, null); } if (description != null) { // If the original content was not TEXT, the formatting is lost entry.setContent( TextConstruct.create(TextConstruct.Type.TEXT, description, null)); } for (String ingredient : mainIngredient) { entry.getGoogleBaseAttributes().addTextAttribute( MAIN_INGREDIENT_ATTRIBUTE, ingredient); } for (String cuisineItem : cuisine) { entry.getGoogleBaseAttributes().addTextAttribute( CUISINE_ATTRIBUTE, cuisineItem); } if (cookingTime != null) { entry.getGoogleBaseAttributes().addIntUnitAttribute( COOKING_TIME_ATTRIBUTE, cookingTime); } return entry; } /** * Extracts the id of the item from the given url. * * The id found in GoogleBaseEntry is a URL that contains the real, numerical * id of the item in Google Base. Parsing the URL is unfortunately the * only way of getting a numerical id given a GoogleBaseEntry. * * @param url a URL that ends with "/" [N] number */ private static String extractIdFromUrl(String url) { int lastSlash = url.lastIndexOf('/'); if (lastSlash == -1 || lastSlash == (url.length()-1)) { throw new IllegalArgumentException("Id is in a strange format. " + url); } String oid = url.substring(lastSlash + 1); return oid; } /** Checks whether there is a description for the recipe. */ public boolean hasDescription() { return description != null; } /** Checks whether there is a cooking time for the recipe. */ public boolean hasCookingTime() { return cookingTime != null; } /** Checks whether there are some cuisines for the recipe. */ public boolean hasCuisine() { return cuisine.size() > 0; } /** Checks whether there are some main ingredients for the recipe. */ public boolean hasMainIngredient() { return mainIngredient.size() > 0; } /** * Gets the date at which the recipe was posted, as a string. * * @param detailed set to true to get a full date and time */ public String getPostedOnAsString(boolean detailed) { Date date = new Date(postedOn.getValue()); String template = detailed ? "MMMMM d, yyyy HH:mm z" : "MMM d"; DateFormat format = new SimpleDateFormat(template); return format.format(date); } /** Gets the host and protocol from the recipe URL. */ public String getHostAndProtocol() throws MalformedURLException { URL urlObject = new URL(getUrl()); return urlObject.getProtocol() + "://" + urlObject.getHost(); } /** * Returns true when the title, description, mainIngredient and cuisine * attributes are not null nor empty. */ public boolean isComplete() { return title != null && description != null && mainIngredient.size() > 0 && cuisine.size() > 0; } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Recipe["); appendNamedParameter(sb, "title", title); appendNamedParameter(sb, "id", id); appendNamedParameter(sb, "url", url); appendNamedParameter(sb, "description", description); appendNamedParameter(sb, "cookingTime", cookingTime); appendNamedParameter(sb, "postedOn", postedOn); appendNamedParameter(sb, "postedBy", postedBy); appendNamedCollection(sb, "mainIngredient", mainIngredient); appendNamedCollection(sb, "cuisine", cuisine); sb.append("]"); return sb.toString(); } /** * Appends the name and the value of an Object to a StringBuffer. * * @param sb * @param name * @param value */ private static void appendNamedParameter(StringBuffer sb, String name, Object value) { if (value != null) { sb.append(name).append("=\"").append(value).append("\" "); } } /** * Appends the name and the elements of a Collection to a StringBuffer. * * @param sb * @param name * @param collection */ private static void appendNamedCollection( StringBuffer sb, String name, Collection<String> collection) { if (collection.size() > 0) { sb.append(name).append("=("); for (String value : collection) { sb.append("\"").append(value).append("\", "); } sb.append(") "); } } /** Gets the id generated by the server. */ public String getId() { return id; } /** Gets the user assigned title. */ public String getTitle() { return title; } /** * Gets the url of the recipe, as set by the customer. * If the customer sets no url, the server will generate one. */ public String getUrl() { return url; } /** Gets the user assigned description. */ public String getDescription() { return description; } /** Returns a never-null Set with the main ingredients of the recipe. */ public Set<String> getMainIngredient() { return mainIngredient; } /** Returns a never-null Set with the cuisines the recipe belongs to. */ public Set<String> getCuisine() { return cuisine; } /** Gets the user assigned cooking time. */ public NumberUnit<Integer> getCookingTime() { return cookingTime; } /** Gets the server generated owner attribute of the recipe. */ public String getPostedBy() { return postedBy; } /** Gets the server generated date at which the recipe was posted. */ public DateTime getPostedOn() { return postedOn; } /** Returns true when the Recipe doesn't have an id. */ public boolean isNew() { return id == null; } }