Java tutorial
/** * Copyright 2010 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 com.google.livingstories.client.lsp; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayInteger; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.Dictionary; import com.google.gwt.user.client.Window; import com.google.livingstories.client.AssetContentItem; import com.google.livingstories.client.AssetType; import com.google.livingstories.client.BackgroundContentItem; import com.google.livingstories.client.BaseContentItem; import com.google.livingstories.client.ContentItemType; import com.google.livingstories.client.DataContentItem; import com.google.livingstories.client.EventContentItem; import com.google.livingstories.client.Importance; import com.google.livingstories.client.NarrativeContentItem; import com.google.livingstories.client.NarrativeType; import com.google.livingstories.client.PlayerContentItem; import com.google.livingstories.client.PlayerType; import com.google.livingstories.client.QuoteContentItem; import com.google.livingstories.client.ReactionContentItem; import com.google.livingstories.client.util.Constants; import com.google.livingstories.client.util.GlobalUtil; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Defines an api usable by external javascript to access GWT objects. */ public class Externs { private static final DateTimeFormat dateFormat = DateTimeFormat.getFormat("yyyy-MM-dd hh:mm a"); // Initialize a map from the write panel names used in magic fields to the corresponding content // item types private static final Map<String, ContentItemType> panelNamesToContentTypes; static { Map<String, ContentItemType> tempMap = new HashMap<String, ContentItemType>(); tempMap.put("events", ContentItemType.EVENT); tempMap.put("narratives", ContentItemType.NARRATIVE); tempMap.put("players", ContentItemType.PLAYER); tempMap.put("background", ContentItemType.BACKGROUND); tempMap.put("images", ContentItemType.ASSET); tempMap.put("videos", ContentItemType.ASSET); tempMap.put("audio", ContentItemType.ASSET); tempMap.put("graphics", ContentItemType.ASSET); tempMap.put("resources", ContentItemType.ASSET); tempMap.put("documents", ContentItemType.ASSET); tempMap.put("quotes", ContentItemType.QUOTE); tempMap.put("facts", ContentItemType.DATA); tempMap.put("reactions", ContentItemType.REACTION); panelNamesToContentTypes = Collections.unmodifiableMap(tempMap); } private static final Map<String, AssetType> panelNamesToAssetTypes; static { Map<String, AssetType> tempMap = new HashMap<String, AssetType>(); tempMap.put("images", AssetType.IMAGE); tempMap.put("videos", AssetType.VIDEO); tempMap.put("audio", AssetType.AUDIO); tempMap.put("graphics", AssetType.INTERACTIVE); tempMap.put("resources", AssetType.LINK); tempMap.put("documents", AssetType.DOCUMENT); panelNamesToAssetTypes = Collections.unmodifiableMap(tempMap); } private static Map<String, List<String>> currentParameters; private static Set<ContentItemType> coreItemTypes = new HashSet<ContentItemType>(); private static Set<AssetType> coreItemAssetTypes = new HashSet<AssetType>(); private static List<Integer> coreItemIds = new ArrayList<Integer>(); private static Map<Integer, BaseContentItem> contentItemsById = new HashMap<Integer, BaseContentItem>(); private static Map<Integer, String> themesById = new HashMap<Integer, String>(); // Maps from content type to the magic field write panel id for that content type. private static Map<ContentItemType, Integer> contentTypesToPanelIds = new HashMap<ContentItemType, Integer>(); // Maps from asset type to the magic field write panel id for that asset type. private static Map<AssetType, Integer> assetTypesToPanelIds = new HashMap<AssetType, Integer>(); public static void bind() { currentParameters = Window.Location.getParameterMap(); Set<Integer> corePanelIds = new HashSet<Integer>(); JsArrayInteger corePanelIdsJs = getCorePanelIds(); if (corePanelIdsJs != null) { for (int i = 0; i < corePanelIdsJs.length(); i++) { corePanelIds.add(corePanelIdsJs.get(i)); } } Dictionary itemTypes = Dictionary.getDictionary("ITEM_TYPES"); for (String key : itemTypes.keySet()) { String itemType = itemTypes.get(key); int panelId = Integer.valueOf(key); boolean isCurrentFilteredType = corePanelIds.contains(panelId); ContentItemType contentType = getContentTypeForFilters(itemType); if (contentType == null) { throw new IllegalArgumentException("No matching content type: " + itemType); } else if (contentType != ContentItemType.ASSET) { contentTypesToPanelIds.put(contentType, panelId); if (isCurrentFilteredType) { coreItemTypes.add(contentType); } } else { AssetType assetType = getAssetTypeForFilters(itemType); assetTypesToPanelIds.put(assetType, panelId); if (isCurrentFilteredType) { coreItemTypes.add(ContentItemType.ASSET); coreItemAssetTypes.add(assetType); } } } Dictionary themes = Dictionary.getDictionary("THEMES"); for (String key : themes.keySet()) { themesById.put(Integer.valueOf(key), themes.get(key)); } parseContentItems(getContentItemsJs()); } public static ContentItemBundle parseContentItems(JsArray<JsContentItem> contentItemsJs) { ContentItemBundle result = new ContentItemBundle(); for (int i = 0; i < contentItemsJs.length(); i++) { JsContentItem jsItem = contentItemsJs.get(i); BaseContentItem item = createContentItem(jsItem); result.addContentItem(item, isCoreItem(item)); } coreItemIds.addAll(result.getCoreContentIds()); contentItemsById.putAll(result.getContentItemsById()); return result; } public static List<Integer> getCoreItemIds() { return coreItemIds; } public static Map<Integer, BaseContentItem> getContentItemsById() { return contentItemsById; } public static native boolean hasMoreItems() /*-{ return $wnd.HAS_MORE_ITEMS; }-*/; public static native int getLivingStoryId() /*-{ return $wnd.LIVING_STORY_ID; }-*/; public static native String getLivingStorySummary() /*-{ return $wnd.LIVING_STORY_SUMMARY; }-*/; public static Map<Integer, String> getThemesById() { return themesById; } public static Map<ContentItemType, Integer> getContentTypesToPanelIds() { return contentTypesToPanelIds; } public static Map<AssetType, Integer> getAssetTypesToPanelIds() { return assetTypesToPanelIds; } public static native String getTemplateDirectory() /*-{ return $wnd.TEMPLATE_DIRECTORY; }-*/; public static native String getPostLoaderUrl() /*-{ return $wnd.POST_LOADER_URL }-*/; public static native JsArrayInteger getCorePanelIds() /*-{ return $wnd.CORE_ITEM_TYPES; }-*/; public static int getJumpToId() { return currentParameters.containsKey(Constants.JUMP_TO_ID_PARAM) ? Integer.valueOf(currentParameters.get(Constants.JUMP_TO_ID_PARAM).get(0)) : 0; } public static Integer getThemeId() { return currentParameters.containsKey(Constants.THEME_ID_PARAM) ? Integer.valueOf(currentParameters.get(Constants.THEME_ID_PARAM).get(0)) : null; } public static int getFilterPanelId() { return currentParameters.containsKey(Constants.FILTER_PANEL_ID_PARAM) ? Integer.valueOf(currentParameters.get(Constants.FILTER_PANEL_ID_PARAM).get(0)) : 0; } public static int getFilterLinkedPostId() { return currentParameters.containsKey(Constants.FILTER_LINKED_POST_ID_PARAM) ? Integer.valueOf(currentParameters.get(Constants.FILTER_LINKED_POST_ID_PARAM).get(0)) : 0; } public static boolean getFilterImportantOnly() { return currentParameters.containsKey(Constants.FILTER_IMPORTANCE_PARAM) && Constants.FILTER_HIGH_IMPORTANCE_VALUE .equals(currentParameters.get(Constants.FILTER_IMPORTANCE_PARAM).get(0)); } public static boolean getFilterChronological() { return currentParameters.containsKey(Constants.FILTER_ORDER_PARAM) && Constants.FILTER_CHRONOLOGICAL_VALUE .equals(currentParameters.get(Constants.FILTER_ORDER_PARAM).get(0)); } // Determine if the given item is a 'core' item, which we will show at the top // level in the content list. private static boolean isCoreItem(BaseContentItem item) { if (coreItemTypes.isEmpty()) { // All items are considered 'core' if no types are explicitly specified. return true; } else if (coreItemTypes.contains(item.getContentItemType())) { // Otherwise, make sure the coreItemTypes/coreItemAssetTypes contains // this item's type. return item.getContentItemType() != ContentItemType.ASSET || coreItemAssetTypes.contains(((AssetContentItem) item).getAssetType()); } else { // Didn't match a core type, so this is not a core item. return false; } } // Get the content type equivalent for the given write panel name, for use with // the filters. private static ContentItemType getContentTypeForFilters(String panelName) { return panelNamesToContentTypes.get(panelName.toLowerCase()); } // Get the asset type equivalent for the given write panel name, for use with // the filters. private static AssetType getAssetTypeForFilters(String panelName) { AssetType assetType = panelNamesToAssetTypes.get(panelName.toLowerCase()); if (assetType == AssetType.DOCUMENT) { // Note that for filtering purposes, we treat put documents under the same // filter as links. assetType = AssetType.LINK; } return assetType; } // Method to parse the JSON response from a 'read more' request. // Automatically changes the 'has more items' field based on the response data. public static native JsArray<JsContentItem> parseReadMoreJSON(String json) /*-{ // Parens are necessary to prevent 'invalid label' errors when evaling json. // This is due to an ambiguity in javascript syntax that makes eval think the // JSON is actually a code label. var response = eval("(" + json + ")"); $wnd.HAS_MORE_ITEMS = response["HAS_MORE_ITEMS"]; return response["CONTENT_ITEMS"]; }-*/; private static native JsArray<JsContentItem> getContentItemsJs() /*-{ return $wnd.CONTENT_ITEMS; }-*/; private static class JsContentItem extends JavaScriptObject { protected JsContentItem() { } /*** Common methods ***/ public final int getId() { return getPositiveIntValue("id"); } public final ContentItemType getContentItemType() { String panelName = getStringValue("panelName"); return GlobalUtil.isContentEmpty(panelName) ? null : panelNamesToContentTypes.get(panelName); } public final Date getTimestamp() { String timestampString = getStringValue("timestamp"); return GlobalUtil.isContentEmpty(timestampString) ? null : dateFormat.parse(timestampString); } public final Importance getImportance() { String importanceString = getStringValue("importance"); return GlobalUtil.isContentEmpty(importanceString) ? Importance.MEDIUM : Importance.valueOf(importanceString); } public final Set<Integer> getLinkedContentIds() { String idSetString = getStringValue("linkedContentIds"); return GlobalUtil.isContentEmpty(idSetString) ? new HashSet<Integer>() : getIdSet(idSetString); } public final String getContent() { return getStringValue("content"); } public final String getAuthorsString() { return getStringValue("authorsString"); } public final int getAuthorsCount() { return getPositiveIntValue("authorsCount"); } /*** Common event and narrative methods ***/ public final String getUpdate() { return getStringValue("update"); } public final String getSummary() { return getStringValue("summary"); } /*** Event methods ***/ public final Date getEventDate() { return getDate(getStringValue("eventDate"), getStringValue("eventTime")); } /*** Narrative methods ***/ public final Date getNarrativeDate() { return getDate(getStringValue("narrativeDate"), getStringValue("narrativeTime")); } public final NarrativeType getNarrativeType() { String narrativeTypeString = getStringValue("narrativeType"); return GlobalUtil.isContentEmpty(narrativeTypeString) ? NarrativeType.FEATURE : NarrativeType.valueOf(narrativeTypeString.toUpperCase().replace("-", "_").replace(" ", "_")); } /*** Player methods ***/ public final String getPlayerName() { return getStringValue("playerName"); } public final List<String> getPlayerAliases() { List<String> aliasList = new ArrayList<String>(); String aliases = getStringValue("playerAliases"); if (!GlobalUtil.isContentEmpty(aliases)) { for (String alias : aliases.split(",")) { String trimmed = alias.trim(); if (!trimmed.isEmpty()) { aliasList.add(trimmed); } } } return aliasList; } public final PlayerType getPlayerType() { String playerTypeString = getStringValue("playerType"); return GlobalUtil.isContentEmpty(playerTypeString) ? PlayerType.PERSON : PlayerType.valueOf(playerTypeString.toUpperCase()); } public final int getPlayerPhotoId() { return getPositiveIntValue("playerPhoto"); } /*** Common asset methods ***/ public final AssetType getAssetType() { String assetTypeString = getStringValue("assetType"); return GlobalUtil.isContentEmpty(assetTypeString) ? null : AssetType.valueOf(assetTypeString); } public final String getPreviewUrl() { return getStringValue("previewUrl"); } public final String getCaption() { return getStringValue("caption"); } /*** Image methods ***/ public final String getImageUrl() { return getStringValue("imageUrl"); } /*** Background methods ***/ public final String getConceptName() { return getStringValue("conceptName"); } /*** Internal methods ***/ private final native String getStringValue(String key) /*-{ return this[key]; }-*/; public final native int getPositiveIntValue(String key) /*-{ if (this[key]) { return this[key]; } else { return 0; } }-*/; private final Date getDate(String dateString, String timeString) { if (GlobalUtil.isContentEmpty(timeString)) { timeString = "12:00 am"; } return GlobalUtil.isContentEmpty(dateString) ? null : dateFormat.parse(dateString + " " + (timeString.trim())); } private Set<Integer> getIdSet(String idString) { Set<Integer> idSet = new HashSet<Integer>(); if (!idString.isEmpty()) { String[] ids = idString.split(","); for (String id : ids) { idSet.add(Integer.valueOf(id)); } } return idSet; } } private static BaseContentItem createContentItem(JsContentItem item) { BaseContentItem content; switch (item.getContentItemType()) { case EVENT: content = new EventContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), item.getImportance(), item.getEventDate(), item.getUpdate(), item.getSummary(), item.getContent()); break; case NARRATIVE: content = new NarrativeContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), item.getContent(), item.getImportance(), item.getUpdate(), item.getNarrativeType(), true, // TODO: put the real value of isStandalone here item.getNarrativeDate(), item.getSummary()); break; case PLAYER: content = new PlayerContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), item.getContent(), item.getImportance(), item.getPlayerName(), item.getPlayerAliases(), item.getPlayerType(), null); // TODO: replace with actual AssetContentItem if the photoId != -1 break; case ASSET: AssetType assetType = item.getAssetType(); content = new AssetContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), assetType == AssetType.IMAGE ? item.getImageUrl() : item.getContent(), item.getImportance(), assetType, item.getCaption(), item.getPreviewUrl()); break; case BACKGROUND: content = new BackgroundContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), item.getContent(), item.getImportance(), item.getConceptName()); break; case QUOTE: content = new QuoteContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), item.getContent(), item.getImportance()); break; case DATA: content = new DataContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), item.getContent(), item.getImportance()); break; case REACTION: content = new ReactionContentItem(item.getId(), item.getTimestamp(), item.getAuthorsString(), item.getAuthorsCount(), item.getContent(), item.getImportance()); break; default: return null; } content.setLinkedContentItemIds(item.getLinkedContentIds()); return content; } }