/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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.apache.pivot.demos.itunes;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Comparator;
import java.util.Locale;
import org.apache.pivot.beans.BXML;
import org.apache.pivot.beans.BXMLSerializer;
import org.apache.pivot.collections.List;
import org.apache.pivot.collections.Map;
import org.apache.pivot.util.concurrent.Task;
import org.apache.pivot.util.concurrent.TaskListener;
import org.apache.pivot.web.GetQuery;
import org.apache.pivot.wtk.ActivityIndicator;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtk.BoxPane;
import org.apache.pivot.wtk.ImageView;
import org.apache.pivot.wtk.Label;
import org.apache.pivot.wtk.PushButton;
import org.apache.pivot.wtk.TableView;
import org.apache.pivot.wtk.TaskAdapter;
import org.apache.pivot.wtk.TextInput;
import org.apache.pivot.wtk.Window;
import org.apache.pivot.wtk.media.Image;
public class SearchDemo implements Application {
private Window window = null;
@BXML private TextInput termTextInput;
@BXML private PushButton searchButton;
@BXML private Label statusLabel;
@BXML private TableView resultsTableView;
@BXML private BoxPane activityIndicatorBoxPane;
@BXML private ActivityIndicator activityIndicator;
@BXML private ImageView artworkImageView;
@BXML private PushButton previewButton;
private GetQuery getQuery = null;
private final Image searchImage;
private final Image cancelImage;
public static final String APPLICATION_KEY = "application";
public static final String QUERY_HOSTNAME = "ax.phobos.apple.com.edgesuite.net";
public static final String BASE_QUERY_PATH = "/WebObjects/MZStoreServices.woa/wa/itmsSearch";
public static final String MEDIA = "all";
public static final int LIMIT = 100;
public SearchDemo() throws Exception {
searchImage = Image.load(getClass().getResource("magnifier.png"));
cancelImage = Image.load(getClass().getResource("bullet_cross.png"));
}
@Override
public void startup(Display display, Map<String, String> properties) throws Exception {
BXMLSerializer bxmlSerializer = new BXMLSerializer();
bxmlSerializer.getNamespace().put(APPLICATION_KEY, this);
window = (Window)bxmlSerializer.readObject(SearchDemo.class, "search_demo.bxml");
bxmlSerializer.bind(this, SearchDemo.class);
searchButton.setButtonData(searchImage);
window.open(display);
termTextInput.requestFocus();
}
@Override
public boolean shutdown(boolean optional) {
if (window != null) {
window.close();
}
return false;
}
@Override
public void suspend() {
// No-op
}
@Override
public void resume() {
// No-op
}
/**
* Executes a search.
*
* @param term
* The search term.
*
* @throws IllegalArgumentException
* If <tt>term</tt> is <tt>null</tt> or empty.
*
* @throws IllegalStateException
* If a query is already executing.
*/
@SuppressWarnings("unchecked")
public void executeQuery(String term) {
if (term == null
|| term.length() == 0) {
throw new IllegalArgumentException();
}
if (getQuery != null) {
throw new IllegalStateException();
}
String country = Locale.getDefault().getCountry().toLowerCase();
getQuery = new GetQuery(QUERY_HOSTNAME, BASE_QUERY_PATH);
getQuery.getParameters().put("term", term);
getQuery.getParameters().put("country", country);
getQuery.getParameters().put("media", MEDIA);
getQuery.getParameters().put("limit", Integer.toString(LIMIT));
getQuery.getParameters().put("output", "json");
System.out.println(getQuery.getLocation());
statusLabel.setText("Searching...");
updateActivityState();
getQuery.execute(new TaskAdapter<Object>(new TaskListener<Object>() {
@Override
public void taskExecuted(Task<Object> task) {
if (task == getQuery) {
Map<String, Object> result = (Map<String, Object>)task.getResult();
List<Object> results = (List<Object>)result.get("results");
// Preserve any existing sort
List<Object> tableData = (List<Object>)resultsTableView.getTableData();
Comparator<Object> comparator = tableData.getComparator();
results.setComparator(comparator);
// Update the table data
resultsTableView.setTableData(results);
statusLabel.setText("Found " + results.getLength() + " matching items.");
getQuery = null;
updateActivityState();
if (results.getLength() > 0) {
resultsTableView.setSelectedIndex(0);
resultsTableView.requestFocus();
} else {
termTextInput.requestFocus();
}
}
}
@Override
public void executeFailed(Task<Object> task) {
if (task == getQuery) {
statusLabel.setText(task.getFault().getMessage());
getQuery = null;
updateActivityState();
termTextInput.requestFocus();
}
}
}));
}
/**
* Aborts an executing query.
*
* @throws IllegalStateException
* If a query is not currently executing.
*/
public void abortQuery() {
if (getQuery == null) {
throw new IllegalStateException();
}
getQuery.abort();
getQuery = null;
updateActivityState();
}
/**
* Tests whether a query is currently executing.
*
* @return
* <tt>true</tt> if a query is currently executing; <tt>false</tt>,
* otherwise.
*/
public boolean isQueryExecuting() {
return (getQuery != null);
}
private void updateActivityState() {
boolean active = (getQuery != null);
activityIndicatorBoxPane.setVisible(active);
activityIndicator.setActive(active);
termTextInput.setEnabled(!active);
searchButton.setButtonData(active ? cancelImage : searchImage);
}
/**
* Updates the artwork to reflect the current selection.
*/
@SuppressWarnings("unchecked")
public void updateArtwork() {
Map<String, Object> result = (Map<String, Object>)resultsTableView.getSelectedRow();
URL artworkURL = null;
if (result != null) {
try {
artworkURL = new URL((String)result.get("artworkUrl100"));
} catch (MalformedURLException exception) {
}
}
if (artworkURL == null) {
artworkImageView.setImage((Image)null);
} else {
Image.load(artworkURL, new TaskAdapter<Image>(new TaskListener<Image>() {
@Override
public void taskExecuted(Task<Image> task) {
artworkImageView.setImage(task.getResult());
}
@Override
public void executeFailed(Task<Image> task) {
artworkImageView.setImage((Image)null);
}
}));
}
previewButton.setEnabled(result != null);
}
public static void main(String[] args) {
DesktopApplicationContext.main(SearchDemo.class, args);
}
}