Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8ffe624 authored by Joseph Wen's avatar Joseph Wen Committed by Android (Google) Code Review
Browse files

Merge "Update Statement Service." into mnc-dev

parents 59b28c0c 3bbc9099
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -16,6 +16,13 @@

package com.android.statementservice.retriever;

import android.util.JsonReader;

import org.json.JSONException;

import java.io.IOException;
import java.io.StringReader;

/**
 * A handle representing the identity and address of some digital asset. An asset is an online
 * entity that typically provides some service or content. Examples of assets are websites, Android
@@ -61,7 +68,14 @@ public abstract class AbstractAsset {
     */
    public static AbstractAsset create(String assetJson)
            throws AssociationServiceException {
        return AssetFactory.create(assetJson);
        JsonReader reader = new JsonReader(new StringReader(assetJson));
        reader.setLenient(false);
        try {
            return AssetFactory.create(JsonParser.parse(reader));
        } catch (JSONException | IOException e) {
            throw new AssociationServiceException(
                    "Input is not a well formatted asset descriptor.", e);
        }
    }

    /**
+1 −16
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.statementservice.retriever;

import org.json.JSONException;
import org.json.JSONObject;

/**
@@ -28,26 +27,12 @@ import org.json.JSONObject;

    private AssetFactory() {}

    /**
     * Creates a new Asset object from its JSON string representation.
     *
     * @throws AssociationServiceException if the assetJson is not well formatted.
     */
    public static AbstractAsset create(String assetJson) throws AssociationServiceException {
        try {
            return create(new JSONObject(assetJson));
        } catch (JSONException e) {
            throw new AssociationServiceException(
                    "Input is not a well formatted asset descriptor.");
        }
    }

    /**
     * Checks that the input is a valid asset with purposes.
     *
     * @throws AssociationServiceException if the asset is not well formatted.
     */
    private static AbstractAsset create(JSONObject asset)
    public static AbstractAsset create(JSONObject asset)
            throws AssociationServiceException {
        String namespace = asset.optString(Utils.NAMESPACE_FIELD, null);
        if (namespace == null) {
+2 −2
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ import java.util.List;
                                .getStatements());
            }
            return Result.create(statements, webContent.getExpireTimeMillis());
        } catch (JSONException e) {
        } catch (JSONException | IOException e) {
            return Result.create(statements, DO_NOT_CACHE_RESULT);
        }
    }
@@ -202,7 +202,7 @@ import java.util.List;
            }

            return Result.create(statements, DO_NOT_CACHE_RESULT);
        } catch (JSONException | NameNotFoundException e) {
        } catch (JSONException | IOException | NameNotFoundException e) {
            Log.w(DirectStatementRetriever.class.getSimpleName(), e);
            return Result.create(Collections.<Statement>emptyList(), DO_NOT_CACHE_RESULT);
        }
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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 com.android.statementservice.retriever;

import android.util.JsonReader;
import android.util.JsonToken;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * A helper class that creates a {@link JSONObject} from a {@link JsonReader}.
 */
public final class JsonParser {

    private JsonParser() {}

    /**
     * Consumes and parses exactly one JSON object from the {@link JsonReader}.
     * The object's fields can only be objects, strings or arrays of strings.
     */
    public static JSONObject parse(JsonReader reader) throws IOException, JSONException {
        JSONObject output = new JSONObject();
        String errorMsg = null;

        reader.beginObject();
        while (reader.hasNext()) {
            String fieldName = reader.nextName();

            if (output.has(fieldName)) {
                errorMsg = "Duplicate field name.";
                reader.skipValue();
                continue;
            }

            JsonToken token = reader.peek();
            if (token.equals(JsonToken.BEGIN_ARRAY)) {
                output.put(fieldName, new JSONArray(parseArray(reader)));
            } else if (token.equals(JsonToken.STRING)) {
                output.put(fieldName, reader.nextString());
            } else if (token.equals(JsonToken.BEGIN_OBJECT)) {
                try {
                    output.put(fieldName, parse(reader));
                } catch (JSONException e) {
                    errorMsg = e.getMessage();
                }
            } else {
                reader.skipValue();
                errorMsg = "Unsupported value type.";
            }
        }
        reader.endObject();

        if (errorMsg != null) {
            throw new JSONException(errorMsg);
        }

        return output;
    }

    /**
     * Parses one string array from the {@link JsonReader}.
     */
    public static List<String> parseArray(JsonReader reader) throws IOException {
        ArrayList<String> output = new ArrayList<>();

        reader.beginArray();
        while (reader.hasNext()) {
            output.add(reader.nextString());
        }
        reader.endArray();

        return output;
    }
}
+49 −10
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package com.android.statementservice.retriever;

import android.util.JsonReader;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

@@ -28,20 +32,33 @@ import java.util.List;
 */
/* package private */ final class StatementParser {

    private static final String FIELD_NOT_STRING_FORMAT_STRING = "Expected %s to be string.";
    private static final String FIELD_NOT_ARRAY_FORMAT_STRING = "Expected %s to be array.";

    /**
     * Parses a JSON array of statements.
     */
    static ParsedStatement parseStatementList(String statementList, AbstractAsset source)
            throws JSONException, AssociationServiceException {
            throws JSONException, IOException {
        List<Statement> statements = new ArrayList<Statement>();
        List<String> delegates = new ArrayList<String>();

        JSONArray statementsJson = new JSONArray(statementList);
        for (int i = 0; i < statementsJson.length(); i++) {
            ParsedStatement result = parseStatement(statementsJson.getString(i), source);
        JsonReader reader = new JsonReader(new StringReader(statementList));
        reader.setLenient(false);

        reader.beginArray();
        while (reader.hasNext()) {
            ParsedStatement result;
            try {
                result = parseStatement(reader, source);
            } catch (AssociationServiceException e) {
                // The element in the array is well formatted Json but not a well-formed Statement.
                continue;
            }
            statements.addAll(result.getStatements());
            delegates.addAll(result.getDelegates());
        }
        reader.endArray();

        return new ParsedStatement(statements, delegates);
    }
@@ -50,17 +67,39 @@ import java.util.List;
     * Parses a single JSON statement.
     */
    static ParsedStatement parseStatement(String statementString, AbstractAsset source)
            throws JSONException, AssociationServiceException {
            throws AssociationServiceException, IOException, JSONException {
        JsonReader reader = new JsonReader(new StringReader(statementString));
        reader.setLenient(false);
        return parseStatement(reader, source);
    }

    /**
     * Parses a single JSON statement. This method guarantees that exactly one JSON object
     * will be consumed.
     */
    static ParsedStatement parseStatement(JsonReader reader, AbstractAsset source)
            throws JSONException, AssociationServiceException, IOException {
        List<Statement> statements = new ArrayList<Statement>();
        List<String> delegates = new ArrayList<String>();
        JSONObject statement = new JSONObject(statementString);

        JSONObject statement = JsonParser.parse(reader);

        if (statement.optString(Utils.DELEGATE_FIELD_DELEGATE, null) != null) {
            delegates.add(statement.optString(Utils.DELEGATE_FIELD_DELEGATE));
        } else {
            AbstractAsset target = AssetFactory
                    .create(statement.getString(Utils.ASSET_DESCRIPTOR_FIELD_TARGET));
            JSONArray relations = statement.getJSONArray(
                    Utils.ASSET_DESCRIPTOR_FIELD_RELATION);
            JSONObject targetObject = statement.optJSONObject(Utils.ASSET_DESCRIPTOR_FIELD_TARGET);
            if (targetObject == null) {
                throw new AssociationServiceException(String.format(
                        FIELD_NOT_STRING_FORMAT_STRING, Utils.ASSET_DESCRIPTOR_FIELD_TARGET));
            }

            JSONArray relations = statement.optJSONArray(Utils.ASSET_DESCRIPTOR_FIELD_RELATION);
            if (relations == null) {
                throw new AssociationServiceException(String.format(
                        FIELD_NOT_ARRAY_FORMAT_STRING, Utils.ASSET_DESCRIPTOR_FIELD_RELATION));
            }

            AbstractAsset target = AssetFactory.create(targetObject);
            for (int i = 0; i < relations.length(); i++) {
                statements.add(Statement
                        .create(source, target, Relation.create(relations.getString(i))));