michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.sync.net; michael@0: michael@0: import java.io.UnsupportedEncodingException; michael@0: import java.net.URI; michael@0: import java.net.URISyntaxException; michael@0: michael@0: import org.json.simple.JSONArray; michael@0: import org.json.simple.JSONObject; michael@0: import org.mozilla.gecko.sync.CryptoRecord; michael@0: import org.mozilla.gecko.sync.ThreadPool; michael@0: michael@0: /** michael@0: * Resource class that implements expected headers and processing for Sync. michael@0: * Accepts a simplified delegate. michael@0: * michael@0: * Includes: michael@0: * * Basic Auth headers (via Resource) michael@0: * * Error responses: michael@0: * * 401 michael@0: * * 503 michael@0: * * Headers: michael@0: * * Retry-After michael@0: * * X-Weave-Backoff michael@0: * * X-Backoff michael@0: * * X-Weave-Records? michael@0: * * ... michael@0: * * Timeouts michael@0: * * Network errors michael@0: * * application/newlines michael@0: * * JSON parsing michael@0: * * Content-Type and Content-Length validation. michael@0: */ michael@0: public class SyncStorageRecordRequest extends SyncStorageRequest { michael@0: michael@0: public class SyncStorageRecordResourceDelegate extends SyncStorageResourceDelegate { michael@0: SyncStorageRecordResourceDelegate(SyncStorageRequest request) { michael@0: super(request); michael@0: } michael@0: } michael@0: michael@0: public SyncStorageRecordRequest(URI uri) { michael@0: super(uri); michael@0: } michael@0: michael@0: public SyncStorageRecordRequest(String url) throws URISyntaxException { michael@0: this(new URI(url)); michael@0: } michael@0: michael@0: @Override michael@0: protected BaseResourceDelegate makeResourceDelegate(SyncStorageRequest request) { michael@0: return new SyncStorageRecordResourceDelegate(request); michael@0: } michael@0: michael@0: @SuppressWarnings("unchecked") michael@0: public void post(JSONObject body) { michael@0: // Let's do this the trivial way for now. michael@0: // Note that POSTs should be an array, so we wrap here. michael@0: final JSONArray toPOST = new JSONArray(); michael@0: toPOST.add(body); michael@0: try { michael@0: this.resource.post(toPOST); michael@0: } catch (UnsupportedEncodingException e) { michael@0: this.delegate.handleRequestError(e); michael@0: } michael@0: } michael@0: michael@0: public void post(JSONArray body) { michael@0: // Let's do this the trivial way for now. michael@0: try { michael@0: this.resource.post(body); michael@0: } catch (UnsupportedEncodingException e) { michael@0: this.delegate.handleRequestError(e); michael@0: } michael@0: } michael@0: michael@0: public void put(JSONObject body) { michael@0: // Let's do this the trivial way for now. michael@0: try { michael@0: this.resource.put(body); michael@0: } catch (UnsupportedEncodingException e) { michael@0: this.delegate.handleRequestError(e); michael@0: } michael@0: } michael@0: michael@0: public void post(CryptoRecord record) { michael@0: this.post(record.toJSONObject()); michael@0: } michael@0: michael@0: public void put(CryptoRecord record) { michael@0: this.put(record.toJSONObject()); michael@0: } michael@0: michael@0: public void deferGet() { michael@0: final SyncStorageRecordRequest self = this; michael@0: ThreadPool.run(new Runnable() { michael@0: @Override michael@0: public void run() { michael@0: self.get(); michael@0: }}); michael@0: } michael@0: michael@0: public void deferPut(final JSONObject body) { michael@0: final SyncStorageRecordRequest self = this; michael@0: ThreadPool.run(new Runnable() { michael@0: @Override michael@0: public void run() { michael@0: self.put(body); michael@0: }}); michael@0: } michael@0: }