/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2014 Boundless * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.cluster; import static com.google.common.base.Objects.equal; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import javax.annotation.Nullable; import org.geoserver.catalog.AttributionInfo; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CoverageInfo; import org.geoserver.catalog.CoverageStoreInfo; import org.geoserver.catalog.DataStoreInfo; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.Info; import org.geoserver.catalog.LayerGroupInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.MetadataLinkInfo; import org.geoserver.catalog.NamespaceInfo; import org.geoserver.catalog.StyleInfo; import org.geoserver.catalog.WMSLayerInfo; import org.geoserver.catalog.WMSStoreInfo; import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.catalog.impl.AttributionInfoImpl; import org.geoserver.catalog.impl.CatalogImpl; import org.geoserver.catalog.impl.CoverageInfoImpl; import org.geoserver.catalog.impl.CoverageStoreInfoImpl; import org.geoserver.catalog.impl.DataStoreInfoImpl; import org.geoserver.catalog.impl.FeatureTypeInfoImpl; import org.geoserver.catalog.impl.LayerGroupInfoImpl; import org.geoserver.catalog.impl.LayerInfoImpl; import org.geoserver.catalog.impl.MetadataLinkInfoImpl; import org.geoserver.catalog.impl.NamespaceInfoImpl; import org.geoserver.catalog.impl.StyleInfoImpl; import org.geoserver.catalog.impl.WMSLayerInfoImpl; import org.geoserver.catalog.impl.WMSStoreInfoImpl; import org.geoserver.catalog.impl.WorkspaceInfoImpl; import org.geoserver.config.ContactInfo; import org.geoserver.config.GeoServerInfo; import org.geoserver.config.LoggingInfo; import org.geoserver.config.ServiceInfo; import org.geoserver.config.SettingsInfo; import org.geoserver.config.impl.ContactInfoImpl; import org.geoserver.config.impl.GeoServerInfoImpl; import org.geoserver.config.impl.LoggingInfoImpl; import org.geoserver.config.impl.SettingsInfoImpl; import com.google.common.base.Objects; /** * Event for * @author Justin Deoliveira, OpenGeo * */ public class ConfigChangeEvent extends Event { static Map<Class<? extends Info>,Class<? extends Info>> INTERFACES = new HashMap<Class<? extends Info>,Class<? extends Info>>(); static { INTERFACES.put(GeoServerInfoImpl.class, GeoServerInfo.class); INTERFACES.put(SettingsInfoImpl.class, SettingsInfo.class); INTERFACES.put(LoggingInfoImpl.class, LoggingInfo.class); INTERFACES.put(ContactInfoImpl.class, ContactInfo.class); INTERFACES.put(AttributionInfoImpl.class, AttributionInfo.class); //catalog INTERFACES.put(CatalogImpl.class, Catalog.class); INTERFACES.put(NamespaceInfoImpl.class, NamespaceInfo.class); INTERFACES.put(WorkspaceInfoImpl.class, WorkspaceInfo.class); INTERFACES.put(DataStoreInfoImpl.class, DataStoreInfo.class); INTERFACES.put(WMSStoreInfoImpl.class, WMSStoreInfo.class); INTERFACES.put(CoverageStoreInfoImpl.class, CoverageStoreInfo.class); INTERFACES.put(StyleInfoImpl.class, StyleInfo.class); INTERFACES.put(FeatureTypeInfoImpl.class, FeatureTypeInfo.class ); INTERFACES.put(CoverageInfoImpl.class, CoverageInfo.class); INTERFACES.put(WMSLayerInfoImpl.class, WMSLayerInfo.class); INTERFACES.put(MetadataLinkInfoImpl.class, MetadataLinkInfo.class); INTERFACES.put(LayerInfoImpl.class, LayerInfo.class); INTERFACES.put(LayerGroupInfoImpl.class, LayerGroupInfo.class ); } /** serialVersionUID */ private static final long serialVersionUID = 1L; public enum Type { ADD, REMOVE, MODIFY } /** * id of object */ String id; /** * name of object */ String name; /** * name of workspace qualifying the object */ String workspaceId; /** * id of Store object if the modified object was a Resource */ String storeId; /** * class of object */ Class<? extends Info> clazz; /** * type of config change */ Type type; private String nativeName; public ConfigChangeEvent(String id, String name, Class<? extends Info> clazz, Type type) { super(); this.id = id; this.name = name; this.clazz = clazz; this.type = type; } @Override public String toString() { StringBuilder sb = new StringBuilder(String.valueOf(type)).append(" "); Serializable source = getSource(); if (source != null) { sb.append('(').append(source).append(") "); } sb.append("[uuid:").append(getUUID()).append(", object id:").append(id).append(", name:") .append(name).append("]"); return sb.toString(); } /** * Equals is based on {@link #getObjectId() id}, {@link #getObjectName() name}, and * {@link #getChangeType() changeType}. {@link #getObjectClass() class} is left off because it * can be a proxy class and id/name/type are good enough anyways (given ids are unique, no two * objects of different class can have the same id). */ @Override public boolean equals(Object o) { if (!(o instanceof ConfigChangeEvent)) { return false; } ConfigChangeEvent e = (ConfigChangeEvent) o; return equal(id, e.id) && equal(type, e.type); } /** * Hash code is based on {@link #getObjectId() id}, {@link #getObjectName() name}, and * {@link #getChangeType() changeType}. {@link #getObjectClass() class} is left off because it * can be a proxy class and id/name/type are good enough anyways (given ids are unique, no two * objects of different class can have the same id). */ @Override public int hashCode() { return Objects.hashCode(ConfigChangeEvent.class, id, name, type); } public String getObjectId() { return id; } public String getObjectName() { return name; } public String getWorkspaceId() { return workspaceId; } public void setWorkspaceId(String workspaceId) { this.workspaceId = workspaceId; } public String getStoreId() { return storeId; } public void setStoreId(String storeId) { this.storeId = storeId; } public Class<? extends Info> getObjectClass() { return clazz; } public Class<? extends Info> getObjectInterface() { Class<? extends Info> clazz = INTERFACES.get(getObjectClass()); // There are several different ServiceInfo subtypes and it's an extension point // so don't check for specific classes if(clazz==null && ServiceInfo.class.isAssignableFrom(getObjectClass())){ clazz = ServiceInfo.class; } // Fall back, mostly here to support EasyMock test objects in unit tests. if(clazz==null) { for(Class<? extends Info> realClazz: INTERFACES.values()) { if(realClazz.isAssignableFrom(getObjectClass())) { clazz=realClazz; break; } } } return clazz; } public Type getChangeType() { return type; } public void setNativeName(String nativeName) { this.nativeName = nativeName; } @Nullable public String getNativeName() { return nativeName; } }