1 /* 2 * Copyright 2022 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.libraries.mobiledatadownload.file.spi; 17 18 import android.net.Uri; 19 import android.util.Pair; 20 import com.google.android.libraries.mobiledatadownload.file.common.LockScope; 21 import java.io.Closeable; 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.io.OutputStream; 25 import java.util.ArrayList; 26 import java.util.List; 27 28 /** 29 * A backend which forwards all its calls to another backend. Subclasses should override one or more 30 * methods to to modify the behavior of the wrapped backend. 31 */ 32 public abstract class ForwardingBackend implements Backend { 33 34 /** 35 * Gets the backend to which this backend forwards calls. 36 * 37 * @return The delegate. 38 */ delegate()39 protected abstract Backend delegate(); 40 41 /** 42 * Rewrites the Uri to use the delegate's scheme. If subclass calls super.method(), this is 43 * invoked on the Uri before calling method() on delegate. 44 * 45 * <p>This method is a good place to do validation. If the Uri is invalid, implementation should 46 * throw MalformedUriException. 47 * 48 * @param uri The uri that will have its scheme rewritten. 49 * @return The uri with the scheme of the delegate. 50 */ rewriteUri(Uri uri)51 protected Uri rewriteUri(Uri uri) throws IOException { 52 return uri.buildUpon().scheme(delegate().name()).build(); 53 } 54 55 /** 56 * Reverses the rewrite performed by rewriteUri. This is used for directory listing operations. 57 * 58 * @param uri The uri that had its scheme rewritten. 59 * @return The uri with the scheme from this backend. 60 */ reverseRewriteUri(Uri uri)61 protected Uri reverseRewriteUri(Uri uri) throws IOException { 62 return uri.buildUpon().scheme(name()).build(); 63 } 64 65 @Override openForRead(Uri uri)66 public InputStream openForRead(Uri uri) throws IOException { 67 return delegate().openForRead(rewriteUri(uri)); 68 } 69 70 @Override openForNativeRead(Uri uri)71 public Pair<Uri, Closeable> openForNativeRead(Uri uri) throws IOException { 72 return delegate().openForNativeRead(rewriteUri(uri)); 73 } 74 75 @Override openForWrite(Uri uri)76 public OutputStream openForWrite(Uri uri) throws IOException { 77 return delegate().openForWrite(rewriteUri(uri)); 78 } 79 80 @Override openForAppend(Uri uri)81 public OutputStream openForAppend(Uri uri) throws IOException { 82 return delegate().openForAppend(rewriteUri(uri)); 83 } 84 85 @Override deleteFile(Uri uri)86 public void deleteFile(Uri uri) throws IOException { 87 delegate().deleteFile(rewriteUri(uri)); 88 } 89 90 @Override deleteDirectory(Uri uri)91 public void deleteDirectory(Uri uri) throws IOException { 92 delegate().deleteDirectory(rewriteUri(uri)); 93 } 94 95 @Override rename(Uri from, Uri to)96 public void rename(Uri from, Uri to) throws IOException { 97 delegate().rename(rewriteUri(from), rewriteUri(to)); 98 } 99 100 @Override exists(Uri uri)101 public boolean exists(Uri uri) throws IOException { 102 return delegate().exists(rewriteUri(uri)); 103 } 104 105 @Override isDirectory(Uri uri)106 public boolean isDirectory(Uri uri) throws IOException { 107 return delegate().isDirectory(rewriteUri(uri)); 108 } 109 110 @Override createDirectory(Uri uri)111 public void createDirectory(Uri uri) throws IOException { 112 delegate().createDirectory(rewriteUri(uri)); 113 } 114 115 @Override fileSize(Uri uri)116 public long fileSize(Uri uri) throws IOException { 117 return delegate().fileSize(rewriteUri(uri)); 118 } 119 120 @Override children(Uri parentUri)121 public Iterable<Uri> children(Uri parentUri) throws IOException { 122 List<Uri> result = new ArrayList<Uri>(); 123 for (Uri child : delegate().children(rewriteUri(parentUri))) { 124 result.add(reverseRewriteUri(child)); 125 } 126 return result; 127 } 128 129 @Override lockScope()130 public LockScope lockScope() throws IOException { 131 return delegate().lockScope(); 132 } 133 } 134