/* * Copyright (c) 2013 Big Switch Networks, Inc. * * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html * * 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 org.opendaylight.controller.hosttracker.internal; import java.util.EnumSet; import org.opendaylight.controller.hosttracker.Entity; import org.opendaylight.controller.hosttracker.IDeviceService; import org.opendaylight.controller.hosttracker.IDeviceService.DeviceField; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This is a thin wrapper around {@link Entity} that allows overriding the * behavior of {@link Object#hashCode()} and {@link Object#equals(Object)} so * that the keying behavior in a hash map can be changed dynamically * * @author readams */ public class IndexedEntity { protected EnumSet keyFields; protected Entity entity; private int hashCode = 0; protected static Logger logger = LoggerFactory .getLogger(IndexedEntity.class); /** * Create a new {@link IndexedEntity} for the given {@link Entity} using the * provided key fields. * * @param keyFields * The key fields that will be used for computing * {@link IndexedEntity#hashCode()} and * {@link IndexedEntity#equals(Object)} * @param entity * the entity to wrap */ public IndexedEntity(EnumSet keyFields, Entity entity) { super(); this.keyFields = keyFields; this.entity = entity; } /** * Check whether this entity has non-null values in any of its key fields * * @return true if any key fields have a non-null value */ public boolean hasNonNullKeys() { for (DeviceField f : keyFields) { switch (f) { case MAC: return true; case IPV4: if (entity.getIpv4Address() != null) return true; break; case SWITCHPORT: if (entity.getPort() != null) return true; break; case VLAN: if (entity.getVlan() != null) return true; break; } } return false; } @Override public int hashCode() { if (hashCode != 0) { return hashCode; } final int prime = 31; hashCode = 1; for (DeviceField f : keyFields) { switch (f) { case MAC: hashCode = prime * hashCode + (int) (entity.getMacAddress() ^ (entity .getMacAddress() >>> 32)); break; case IPV4: hashCode = prime * hashCode + ((entity.getIpv4Address() == null) ? 0 : entity .getIpv4Address().hashCode()); break; case SWITCHPORT: hashCode = prime * hashCode + ((entity.getPort() == null) ? 0 : entity.getPort() .hashCode()); break; case VLAN: hashCode = prime * hashCode + ((entity.getVlan() == null) ? 0 : entity.getVlan() .hashCode()); break; } } return hashCode; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; IndexedEntity other = (IndexedEntity) obj; if (!keyFields.equals(other.keyFields)) return false; for (IDeviceService.DeviceField f : keyFields) { switch (f) { case MAC: if (entity.getMacAddress() != other.entity.getMacAddress()) return false; break; case IPV4: if (entity.getIpv4Address() == null) { if (other.entity.getIpv4Address() != null) return false; } else if (!entity.getIpv4Address().equals( other.entity.getIpv4Address())) return false; break; case SWITCHPORT: if (entity.getPort() == null) { if (other.entity.getPort() != null) return false; } else if (!entity.getPort().equals(other.entity.getPort())) return false; break; case VLAN: if (entity.getVlan() == null) { if (other.entity.getVlan() != null) return false; } else if (!entity.getVlan().equals(other.entity.getVlan())) return false; break; } } return true; } }