com.android.loganalysis.item.GenericItem.java Source code

Java tutorial

Introduction

Here is the source code for com.android.loganalysis.item.GenericItem.java

Source

/*
 * Copyright (C) 2011 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.loganalysis.item;

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

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * An implementation of the {@link IItem} interface which implements helper methods.
 */
public class GenericItem implements IItem {
    private Map<String, Object> mAttributes = new HashMap<String, Object>();
    private Set<String> mAllowedAttributes;

    protected GenericItem(Set<String> allowedAttributes) {
        mAllowedAttributes = new HashSet<String>();
        mAllowedAttributes.addAll(allowedAttributes);
    }

    protected GenericItem(Set<String> allowedAttributes, Map<String, Object> attributes) {
        this(allowedAttributes);

        for (Map.Entry<String, Object> entry : attributes.entrySet()) {
            setAttribute(entry.getKey(), entry.getValue());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IItem merge(IItem other) throws ConflictingItemException {
        if (this == other) {
            return this;
        }
        if (other == null || getClass() != other.getClass()) {
            throw new ConflictingItemException("Conflicting class types");
        }

        return new GenericItem(mAllowedAttributes, mergeAttributes(other, mAllowedAttributes));
    }

    /**
     * Merges the attributes from the item and another and returns a Map of the merged attributes.
     * <p>
     * Goes through each field in the item preferring non-null attributes over null attributes.
     * </p>
     *
     * @param other The other item
     * @return A Map from Strings to Objects containing merged attributes.
     * @throws ConflictingItemException If the two items are not consistent.
     */
    protected Map<String, Object> mergeAttributes(IItem other, Set<String> attributes)
            throws ConflictingItemException {
        if (this == other) {
            return mAttributes;
        }
        if (other == null || getClass() != other.getClass()) {
            throw new ConflictingItemException("Conflicting class types");
        }

        GenericItem item = (GenericItem) other;
        Map<String, Object> mergedAttributes = new HashMap<String, Object>();
        for (String attribute : attributes) {
            mergedAttributes.put(attribute, mergeObjects(getAttribute(attribute), item.getAttribute(attribute)));
        }
        return mergedAttributes;
    }

    /**
     * {@inhertiDoc}
     */
    @Override
    public boolean isConsistent(IItem other) {
        if (this == other) {
            return true;
        }
        if (other == null || getClass() != other.getClass()) {
            return false;
        }

        GenericItem item = (GenericItem) other;
        for (String attribute : mAllowedAttributes) {
            if (!areConsistent(getAttribute(attribute), item.getAttribute(attribute))) {
                return false;
            }
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other == null || getClass() != other.getClass()) {
            return false;
        }

        GenericItem item = (GenericItem) other;
        for (String attribute : mAllowedAttributes) {
            if (!areEqual(getAttribute(attribute), item.getAttribute(attribute))) {
                return false;
            }
        }
        return true;
    }

    /**
     * {@inheritDoc}
     * <p>
     * This method will only return a JSON object with attributes that the JSON library knows how to
     * encode, along with attributes which implement the {@link IItem} interface.  If objects are
     * stored in this class that fall outside this category, they must be encoded outside of this
     * method.
     * </p>
     */
    @Override
    public JSONObject toJson() {
        JSONObject object = new JSONObject();
        for (Map.Entry<String, Object> entry : mAttributes.entrySet()) {
            final String key = entry.getKey();
            final Object attribute = entry.getValue();
            try {
                if (attribute != null && attribute instanceof IItem) {
                    object.put(key, ((IItem) attribute).toJson());
                } else {
                    object.put(key, attribute);
                }
            } catch (JSONException e) {
                // Ignore
            }
        }
        return object;
    }

    /**
     * Set an attribute to a value.
     *
     * @param attribute The name of the attribute.
     * @param value The value.
     * @throws IllegalArgumentException If the attribute is not in allowedAttributes.
     */
    protected void setAttribute(String attribute, Object value) throws IllegalArgumentException {
        if (!mAllowedAttributes.contains(attribute)) {
            throw new IllegalArgumentException();
        }
        mAttributes.put(attribute, value);
    }

    /**
     * Get the value of an attribute.
     *
     * @param attribute The name of the attribute.
     * @return The value or null if the attribute has not been set.
     * @throws IllegalArgumentException If the attribute is not in allowedAttributes.
     */
    protected Object getAttribute(String attribute) throws IllegalArgumentException {
        if (!mAllowedAttributes.contains(attribute)) {
            throw new IllegalArgumentException();
        }
        return mAttributes.get(attribute);
    }

    /**
     * Helper method to return if two objects are equal.
     *
     * @param object1 The first object
     * @param object2 The second object
     * @return True if object1 and object2 are both null or if object1 is equal to object2, false
     * otherwise.
     */
    static protected boolean areEqual(Object object1, Object object2) {
        return object1 == null ? object2 == null : object1.equals(object2);
    }

    /**
     * Helper method to return if two objects are consistent.
     *
     * @param object1 The first object
     * @param object2 The second object
     * @return True if either object1 or object2 is null or if object1 is equal to object2, false if
     * both objects are not null and not equal.
     */
    static protected boolean areConsistent(Object object1, Object object2) {
        return object1 == null || object2 == null ? true : object1.equals(object2);
    }

    /**
     * Helper method used for merging two objects.
     *
     * @param object1 The first object
     * @param object2 The second object
     * @return If both objects are null, then null, else the non-null item if both items are equal.
     * @throws ConflictingItemException If both objects are not null and they are not equal.
     */
    static protected Object mergeObjects(Object object1, Object object2) throws ConflictingItemException {
        if (!areConsistent(object1, object2)) {
            throw new ConflictingItemException(String.format("%s conflicts with %s", object1, object2));
        }
        return object1 == null ? object2 : object1;
    }
}