Java tutorial
/* * Copyright (c) 2014 by the author(s). * * 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 org.thevortex.lighting.jinks.client; import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.thevortex.lighting.jinks.Subscription; import org.thevortex.lighting.jinks.WinkObject; /** * Simple framework for most service points. * * @author E. A. Graham Jr. */ public abstract class AbstractWinkService<T extends WinkObject> implements WinkService<T> { public static final String ME = "/users/me/"; protected final WinkClient client; protected final Logger logger = LoggerFactory.getLogger(this.getClass()); private final PubNubServiceNotifier<T> notifier; private boolean enableNotify = false; public AbstractWinkService(WinkClient client) { this.client = client; notifier = new PubNubServiceNotifier<>(endpoint(), this::parseItem); } @Override public void enableNotifications(boolean enableNotify) { this.enableNotify = enableNotify; } @Override public void close() { if (notifier != null) notifier.close(); } /** * {@inheritDoc} * <p> * Also initializes listening for events if not already started. This implies the * service subscription does not change over the run-time of the application. * </p> */ @Override public SortedSet<T> getAll() throws IOException { // TODO paginate SortedSet<T> result = new TreeSet<>(); Set<Subscription> itemSubscriptions = new HashSet<>(); Subscription serviceSubscription = null; ObjectNode data = (ObjectNode) client.doGet(ME + endpoint()); if (data.has("data")) { ArrayNode jsonList = (ArrayNode) data.get("data"); for (JsonNode jsonNode : jsonList) { T item = parseItem(jsonNode); if (item != null) { result.add(item); Subscription subscription = item.getSubscription(); if (subscription != null) itemSubscriptions.add(subscription); } } } if (data.has("subscription")) { serviceSubscription = WinkClient.MAPPER.convertValue(data.get("subscription"), Subscription.class); } // if the notifier is enabled, start it up if (enableNotify) notifier.init(serviceSubscription, itemSubscriptions); else if (notifier != null) notifier.close(); return result; } /** * @param data the thing to make * @return the thing post creation * @throws IOException */ public T create(T data) throws IOException { String payload = WinkClient.MAPPER.writeValueAsString(data); JsonNode response = client.doPost(ME + endpoint(), payload); return parseItem(response); } @Override public T get(String id) throws IOException { JsonNode jsonNode = client.doGet(makeUri(id)); return parseItem(jsonNode); } /** * @param data the thing to update * @return the updated item * @throws IOException */ public T update(T data) throws IOException { String payload = WinkClient.MAPPER.writeValueAsString(data); JsonNode response = client.doPut(makeUri(data.getId()), payload); // if we aren't getting responses, re-fetch to ensure freshness return response == null ? get(data.getId()) : parseItem(response); } /** * @param id the ID of the thing to delete * @throws IOException */ public void delete(String id) throws IOException { client.doDelete(makeUri(id)); } /** * @return the name of the thing we're talking to */ protected abstract String endpoint(); /** * @param jsonNode incoming * @return the thing from the data */ public abstract T parseItem(JsonNode jsonNode); /** * How to make a URI for a single thing * * @param id the ID of the thing * @return the URI */ protected String makeUri(String id) { return "/" + endpoint() + "/" + id; } @Override public void addServiceChangeListener(ServiceChangeListener<T> listener) { notifier.addServiceChangeListener(listener); } @Override public void removeServiceChangeListener(ServiceChangeListener<T> listener) { notifier.removeServiceChangeListener(listener); } }