All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.urbanairship.api.push.parse.audience.SelectorReader Maven / Gradle / Ivy

There is a newer version: 9.3.0
Show newest version
/*
 * Copyright (c) 2013-2016.  Urban Airship and Contributors
 */

package com.urbanairship.api.push.parse.audience;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.google.common.collect.ImmutableMap;
import com.urbanairship.api.common.parse.APIParsingException;
import com.urbanairship.api.common.parse.JsonObjectReader;
import com.urbanairship.api.push.model.audience.BasicCompoundSelector;
import com.urbanairship.api.push.model.audience.BasicSelector;
import com.urbanairship.api.push.model.audience.BasicValueSelector;
import com.urbanairship.api.push.model.audience.Selector;
import com.urbanairship.api.push.model.audience.SelectorCategory;
import com.urbanairship.api.push.model.audience.SelectorType;
import com.urbanairship.api.push.model.audience.Selectors;
import com.urbanairship.api.push.model.audience.location.LocationSelector;

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

public class SelectorReader implements JsonObjectReader {

    private BasicSelector.Builder basic = null;
    private BasicValueSelector.Builder value = null;
    private BasicCompoundSelector.Builder compound = null;
    private ImmutableMap.Builder extra = null;
    private LocationSelector location = null;

    public SelectorReader() {
    }

    public void readValueSelector(SelectorType type, JsonParser parser, DeserializationContext context) throws IOException {
        // log.debug("readValueSelector()");
        if (value != null || compound != null ) {
            APIParsingException.raise(String.format("Specified more than one type of selector ('%s' was unexpected)", type.getIdentifier()), parser);
        }
        JsonToken token = parser.getCurrentToken();

        // Simple case, it's a simple value selector
        if (token == JsonToken.VALUE_STRING) {
            value = BasicValueSelector.newBuilder()
                .setType(type)
                .setValue(parser.getText());

            // Complex case, it's an implicit OR expression. Read a
            // list of strings and transform it into an OR of value
            // selectors.
        } else if (token == JsonToken.START_ARRAY) {

            compound = BasicCompoundSelector.newBuilder()
                .setType(SelectorType.OR);

            List values = readListOfStrings(parser);
            for (String value : values) {
                Selector child = Selectors.value(type, value);
                Validation.validate(child);
                compound.addSelector(child);
            }
        }
    }

    public void readCompoundSelector(SelectorType type, JsonParser parser, DeserializationContext context) throws IOException {
        // log.debug("readCompoundSelector() begin: " + parser.getCurrentToken());
        if (value != null || compound != null ) {
            APIParsingException.raise(String.format("Specified more than one type of selector ('%s' was unexpected'", type.getIdentifier()), parser);
        }
        compound = BasicCompoundSelector.newBuilder()
            .setType(type);
        List children = readListOfSelectors(parser, context);
        for (Selector child : children) {
            Validation.validate(child);
        }
        compound.addAllSelectors(children);
        // log.debug("readCompoundSelector() end: " + parser.getCurrentToken());
    }

    public void readLocationSelector(JsonParser parser) throws IOException {
        location = parser.readValueAs(LocationSelector.class);
    }

    public void readExtraField(JsonParser parser) throws IOException {
        if (extra == null) {
            extra = ImmutableMap.builder();
        }
        extra.put(parser.getCurrentName(), parser.getText());
    }

    public List readListOfSelectors(JsonParser parser, DeserializationContext context) throws IOException {
        ArrayList selectors = new ArrayList();
        JsonToken token = parser.getCurrentToken();
        // log.debug("readListOfSelectors() begin: " + token);
        if (token == JsonToken.START_ARRAY) {
            token = parser.nextToken();

            while (token != JsonToken.END_ARRAY) {
                selectors.add(readSelectorInList(parser, context));
                token = parser.nextToken();
            }
        } else if (token == JsonToken.START_OBJECT) {
            selectors.add(readSelectorInList(parser, context));
        }
        // log.debug("readListOfSelectors() end: " + token);
        return selectors;
    }

    private Selector readSelectorInList(JsonParser parser, DeserializationContext context) throws IOException {
        Selector selector = SelectorDeserializer.INSTANCE.deserialize(parser, context);
        if (selector.getType().getCategory() == SelectorCategory.ATOMIC) {
            APIParsingException.raise(String.format("Atomic selector '%s' cannot appear in a compound selector.",
                                                    selector.getType().getIdentifier()), parser);
        }
        Validation.validate(selector);
        return selector;
    }

    public List readListOfStrings(JsonParser parser) throws IOException {
        ArrayList strings = new ArrayList();
        JsonToken token = parser.getCurrentToken();
        // log.debug("readListOfStrings() - " + token);
        if (token == JsonToken.START_ARRAY) {
            token = parser.nextToken();
        }
        while (token != JsonToken.END_ARRAY) {
            if (token != JsonToken.VALUE_STRING) {
                APIParsingException.raise(String.format("Expected a string, but got '%s'", token), parser);
            }
            strings.add(parser.getText());
            token = parser.nextToken();
        }
        return strings;
    }

    @Override
    public Selector validateAndBuild() throws IOException {
        try {
            if (basic != null) {
                return Validation.validate(basic.build());
            } else if (value != null) {
                if (extra != null) {
                    value.addAllAttributes(extra.build());
                }
                return Validation.validate(value.build());
            } else if (compound != null) {
                return Validation.validate(compound.build());
            } else if (location != null ) {
                return location;
            } else {
                throw new APIParsingException("Empty selector.");
            }
        } catch (APIParsingException e) {
            throw e;
        } catch (Exception e) {
            throw new APIParsingException(e.getMessage(), e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy