com.conwet.silbops.model.ContextFunction.java Source code

Java tutorial

Introduction

Here is the source code for com.conwet.silbops.model.ContextFunction.java

Source

package com.conwet.silbops.model;

/*
 * #%L
 * SilboPS API
 * %%
 * Copyright (C) 2011 - 2014 CoNWeT Lab., Universidad Politcnica de Madrid
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import com.conwet.silbops.model.basic.Attribute;
import com.conwet.silbops.model.basic.Value;
import com.conwet.silbops.util.JSONizable;
import com.conwet.silbops.util.externalizer.AttributeExternalizer;
import com.conwet.silbops.util.externalizer.Externalizer;
import com.conwet.silbops.util.externalizer.ValueExternalizer;

/**
 * This class represent the context function used to evaluate context attributes
 * 
 * @author sergio
 */
public class ContextFunction implements JSONizable, Externalizable {

    private static final long serialVersionUID = 1L;
    private static final ValueExternalizer valueExt = new ValueExternalizer();

    private Map<Key, Value> constraint;

    public ContextFunction() {

        constraint = new HashMap<>();
    }

    // copy constructor
    public ContextFunction(ContextFunction other) {

        constraint = new HashMap<>(other.constraint);
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }

        if (obj instanceof ContextFunction) {

            ContextFunction other = (ContextFunction) obj;
            return constraint.equals(other.constraint);
        }

        return false;
    }

    @Override
    public int hashCode() {

        return 83 * this.constraint.hashCode();
    }

    public ContextFunction addConstraint(Attribute pubAttr, Attribute subscriptionAttr, double range) {

        constraint.put(new Key(pubAttr, subscriptionAttr), Value.valueOf(range));
        return this;
    }

    public boolean match(Context cxtPub, Context cxtSub) {

        for (Entry<Key, Value> entry : constraint.entrySet()) {

            Key key = entry.getKey();
            Value cxtPubValue = cxtPub.getValue(key.notAttribute);
            Value cxtSubValue = cxtSub.getValue(key.subscriptionAttribute);

            if (cxtPubValue != null && cxtSubValue != null) {

                double radius = entry.getValue().getDouble();
                double subPos = cxtSubValue.getDouble();
                double pubPos = cxtPubValue.getDouble();

                // it's outside the range
                if (subPos + radius < pubPos || subPos - radius > pubPos) {

                    return false;
                }
            } else {
                return false;
            }
        }

        return true;
    }

    @Override
    public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {

        Map<Key, Value> map = new HashMap<>();
        int size = input.readInt();

        for (int i = 0; i < size; i++) {

            Key key = (Key) input.readObject();
            Value value = valueExt.readExternal(input, key.subscriptionAttribute.getType());
            map.put(key, value);
        }

        constraint = map;
    }

    @Override
    public void writeExternal(ObjectOutput output) throws IOException {

        output.writeInt(constraint.size());

        for (Entry<Key, Value> entry : constraint.entrySet()) {

            output.writeObject(entry.getKey());
            valueExt.writeExternal(output, entry.getValue());
        }
    }

    @SuppressWarnings("unchecked")
    public static ContextFunction fromJSON(JSONObject json) {

        ContextFunction func = new ContextFunction();

        for (Entry<String, JSONArray> entry : (Set<Entry<String, JSONArray>>) json.entrySet()) {

            try {
                JSONObject key = (JSONObject) new JSONParser().parse(entry.getKey());
                Value value = Value.fromJSON(entry.getValue());
                func.constraint.put(Key.fromJSON(key), value);
            } catch (ParseException ex) {
                throw new IllegalArgumentException("Unable to parse Key: " + entry.getKey(), ex);
            }
        }

        return func;
    }

    @Override
    @SuppressWarnings("unchecked")
    public JSONObject toJSON() {

        JSONObject json = new JSONObject();

        for (Entry<Key, Value> entry : constraint.entrySet()) {

            // key must be of String type
            json.put(entry.getKey().toJSONString(), entry.getValue().toJSON());
        }

        return json;
    }

    @Override
    public String toJSONString() {

        return toJSON().toJSONString();
    }

    // key class
    public static class Key implements JSONizable, Externalizable {

        private static final long serialVersionUID = 1L;
        private static final Externalizer<Attribute> attrExt = new AttributeExternalizer();

        private Attribute notAttribute;
        private Attribute subscriptionAttribute;

        public Key() {
            // used by serialization
        }

        public Key(Attribute notAttr, Attribute subscriptionAttr) {

            notAttr = Objects.requireNonNull(notAttr, "Notification attribute is null");
            subscriptionAttr = Objects.requireNonNull(subscriptionAttr, "Subscription attribute is null");

            if (notAttr.getType() != subscriptionAttr.getType()) {

                throw new IllegalArgumentException("Attributes must have same type: " + "notAttr type=" + notAttr
                        + ", subscriptionAttr type=" + subscriptionAttr);
            }

            this.notAttribute = notAttr;
            this.subscriptionAttribute = subscriptionAttr;
        }

        @Override
        public boolean equals(Object obj) {

            if (this == obj) {
                return true;
            }

            if (obj instanceof Key) {

                Key other = (Key) obj;

                return (Objects.equals(notAttribute, other.notAttribute)
                        && Objects.equals(subscriptionAttribute, other.subscriptionAttribute));
            }

            return false;
        }

        @Override
        public int hashCode() {
            int hash = 3;
            hash = 37 * hash + Objects.hashCode(notAttribute);
            hash = 37 * hash + Objects.hashCode(subscriptionAttribute);
            return hash;
        }

        public static Key fromJSON(JSONObject json) {

            Attribute pubAttr = Attribute.fromJSON((String) json.get("notAttr"));
            Attribute subscriptionAttr = Attribute.fromJSON((String) json.get("subscriptionAttr"));

            return new Key(pubAttr, subscriptionAttr);
        }

        @Override
        @SuppressWarnings("unchecked")
        public JSONObject toJSON() {

            JSONObject json = new JSONObject();
            json.put("notAttr", notAttribute.toJSON());
            json.put("subscriptionAttr", subscriptionAttribute.toJSON());

            return json;
        }

        @Override
        public String toJSONString() {

            return toJSON().toJSONString();
        }

        @Override
        public void writeExternal(ObjectOutput output) throws IOException {

            attrExt.writeExternal(output, notAttribute);
            attrExt.writeExternal(output, subscriptionAttribute);
        }

        @Override
        public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {

            notAttribute = attrExt.readExternal(input);
            subscriptionAttribute = attrExt.readExternal(input);
        }

        @Override
        public String toString() {

            return "[notAttribute=" + notAttribute + ", subscriptionAttribute=" + subscriptionAttribute + "]";
        }
    }
}