1 /*
2  * Copyright (C) 2015 The Android Open Source Project
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 
17 package com.android.statementservice.retriever;
18 
19 import android.annotation.NonNull;
20 
21 /**
22  * An immutable value type representing a statement, consisting of a source, target, and relation.
23  * This reflects an assertion that the relation holds for the source, target pair. For example, if a
24  * web site has the following in its assetlinks.json file:
25  *
26  * <pre>
27  * {
28  * "relation": ["delegate_permission/common.handle_all_urls"],
29  * "target"  : {"namespace": "android_app", "package_name": "com.example.app",
30  *              "sha256_cert_fingerprints": ["00:11:22:33"] }
31  * }
32  * </pre>
33  *
34  * Then invoking {@link AbstractStatementRetriever#retrieveStatements(AbstractAsset)} will return a
35  * {@link Statement} with {@link #getSource} equal to the input parameter, {@link #getRelation}
36  * equal to
37  *
38  * <pre>Relation.create("delegate_permission", "common.get_login_creds");</pre>
39  *
40  * and with {@link #getTarget} equal to
41  *
42  * <pre>AbstractAsset.create("{\"namespace\" : \"android_app\","
43  *                           + "\"package_name\": \"com.example.app\"}"
44  *                           + "\"sha256_cert_fingerprints\": \"[\"00:11:22:33\"]\"}");
45  * </pre>
46  */
47 public final class Statement {
48 
49     private final AbstractAsset mTarget;
50     private final Relation mRelation;
51     private final AbstractAsset mSource;
52 
Statement(AbstractAsset source, AbstractAsset target, Relation relation)53     private Statement(AbstractAsset source, AbstractAsset target, Relation relation) {
54         mSource = source;
55         mTarget = target;
56         mRelation = relation;
57     }
58 
59     /**
60      * Returns the source asset of the statement.
61      */
62     @NonNull
getSource()63     public AbstractAsset getSource() {
64         return mSource;
65     }
66 
67     /**
68      * Returns the target asset of the statement.
69      */
70     @NonNull
getTarget()71     public AbstractAsset getTarget() {
72         return mTarget;
73     }
74 
75     /**
76      * Returns the relation of the statement.
77      */
78     @NonNull
getRelation()79     public Relation getRelation() {
80         return mRelation;
81     }
82 
83     /**
84      * Creates a new Statement object for the specified target asset and relation. For example:
85      * <pre>
86      *   Asset asset = Asset.Factory.create(
87      *       "{\"namespace\" : \"web\",\"site\": \"https://www.test.com\"}");
88      *   Relation relation = Relation.create("delegate_permission", "common.get_login_creds");
89      *   Statement statement = Statement.create(asset, relation);
90      * </pre>
91      */
create(@onNull AbstractAsset source, @NonNull AbstractAsset target, @NonNull Relation relation)92     public static Statement create(@NonNull AbstractAsset source, @NonNull AbstractAsset target,
93                                    @NonNull Relation relation) {
94         return new Statement(source, target, relation);
95     }
96 
97     @Override
equals(Object o)98     public boolean equals(Object o) {
99         if (this == o) {
100             return true;
101         }
102         if (o == null || getClass() != o.getClass()) {
103             return false;
104         }
105 
106         Statement statement = (Statement) o;
107 
108         if (!mRelation.equals(statement.mRelation)) {
109             return false;
110         }
111         if (!mTarget.equals(statement.mTarget)) {
112             return false;
113         }
114         if (!mSource.equals(statement.mSource)) {
115             return false;
116         }
117 
118         return true;
119     }
120 
121     @Override
hashCode()122     public int hashCode() {
123         int result = mTarget.hashCode();
124         result = 31 * result + mRelation.hashCode();
125         result = 31 * result + mSource.hashCode();
126         return result;
127     }
128 
129     @Override
toString()130     public String toString() {
131         StringBuilder statement = new StringBuilder();
132         statement.append("Statement: ");
133         statement.append(mSource);
134         statement.append(", ");
135         statement.append(mTarget);
136         statement.append(", ");
137         statement.append(mRelation);
138         return statement.toString();
139     }
140 }
141