/* * Copyright 2008 the original author or authors. * Copyright 2005 Sun Microsystems, Inc. * * 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 org.rioproject.impl.watch; import net.jini.config.Configuration; import net.jini.config.EmptyConfiguration; import org.rioproject.impl.jmx.JMXUtil; import org.rioproject.watch.Calculable; import org.rioproject.watch.WatchDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.openmbean.*; import java.beans.IntrospectionException; import java.lang.reflect.InvocationTargetException; import java.rmi.RemoteException; /** * The Watch provides a mechanism to collect information and associate it to a * WatchDataSource */ public class Watch implements WatchMBean { /** The WatchDataSource associated with this Watch. */ protected WatchDataSource watchDataSource; /** The identifier for this watch. */ protected String id; /** The WatchDataSourceImpl, this may be null if not created by the Watch */ protected WatchDataSourceImpl localRef; /** Use for configuration and logger */ protected static final String COMPONENT = "org.rioproject.watch"; /** A Logger */ private static final Logger logger = LoggerFactory.getLogger(Watch.class); /** Default View class */ public static final String DEFAULT_VIEW = COMPONENT+".DefaultCalculableView"; /** The view */ private String view = DEFAULT_VIEW; /** The configuration*/ private Configuration config; private final Logger dataLogger; /** * Creates new Watch, creates and exports a WatchDataSourceImpl * * @param id The identifier for this watch */ public Watch(String id) { this(id, EmptyConfiguration.INSTANCE); } /** * Creates a new Watch, creates and exports a WatchDataSourceImpl if the * WatchDataSource is null using the Configuration object provided * * @param id The identifier for this watch * @param config Configuration object used for constructing a * WatchDataSource */ public Watch(String id, Configuration config) { if(id == null) throw new IllegalArgumentException("id is null"); if(id.equals("")) throw new IllegalArgumentException("id must not be an empty string"); if(config==null) throw new IllegalArgumentException("config is null"); this.id = id; this.config = config; dataLogger = LoggerFactory.getLogger("watch."+id); try { WatchDataSource wds = (WatchDataSource) config.getEntry(COMPONENT, "watchDataSource", WatchDataSource.class, null); if(wds==null) wds = new WatchDataSourceImpl(); doSetWatchDataSource(wds); } catch(Throwable t) { logger.warn("Creating WatchDataSourceImpl for Watch [{}]", id, t); } } /** * Creates new Watch * * @param id the identifier for this watch * @param watchDataSource the watch data source associated with this watch */ public Watch(WatchDataSource watchDataSource, String id) { if(id == null) throw new IllegalArgumentException("id is null"); if(watchDataSource==null) throw new IllegalArgumentException("watchDataSource is null"); this.id = id; doSetWatchDataSource(watchDataSource); this.watchDataSource = watchDataSource; dataLogger = LoggerFactory.getLogger("watch."+id); } /** * Getter for property watchDataSource. * * @return Value of property watchDataSource. */ public WatchDataSource getWatchDataSource() { return watchDataSource; } /** * Sets the WatchDataSource for the Watch. * * @param wds The new WatchDataSource. The WatchDataSource will * have the id, configuration and view properties injected, and will also * be initialized. */ public void setWatchDataSource(WatchDataSource wds) { if(wds == null) { logger.trace("WatchDataSource is null for Watch={}", id); return; } doSetWatchDataSource(wds); this.watchDataSource = wds; } /* * Setup WatchDataSource */ private void doSetWatchDataSource(WatchDataSource wds) { this.watchDataSource = wds; if(localRef!=null) { localRef.unexport(true); localRef = null; } try { if(config!=null) watchDataSource.setConfiguration(config); watchDataSource.setID(id); watchDataSource.setView(view); if(wds instanceof WatchDataSourceImpl) { localRef = (WatchDataSourceImpl)wds; } watchDataSource.initialize(); if(localRef!=null) { watchDataSource = localRef.getProxy(); } } catch(RemoteException e) { logger.warn("Setting WatchDataSource properties", e); watchDataSource=null; localRef = null; } } /** * Get the view for the Watch * * @return The view for the Watch */ public String getView() { return (view); } /** * Set the view for the Watch * * @param viewClass Fully qualified classname, suitable for use with * Class.forName(), of the class to use to visualize the Watch */ public void setView(String viewClass) { if(viewClass == null) throw new IllegalArgumentException("viewClass is null"); view = viewClass; /* Try direct reference first */ if(localRef != null) localRef.setView(viewClass); else { if(watchDataSource != null) { try { watchDataSource.setView(viewClass); } catch(RemoteException e) { logger.warn("Setting View class for Watch [{}]", getId(), e); } } else { logger.warn("WatchDataSource is null for Watch {}", getId()); } } } /** * @see WatchMBean#getId */ public String getId() { return (id); } /** * @see WatchMBean#getLastCalculableValue */ public double getLastCalculableValue() { double value = 0; try { Calculable lastCalculable; if(localRef != null) lastCalculable = localRef.getLastCalculable(); else lastCalculable = watchDataSource.getLastCalculable(); if(lastCalculable != null) { value = lastCalculable.getValue(); } } catch(Exception e) { logger.warn("Getting last calculable", e); } return(value); } /** * @see WatchMBean#getCalculables */ @SuppressWarnings("unchecked") public TabularData getCalculables(){ try { Calculable[] calculables; if(localRef != null) { calculables = localRef.getCalculable(); } else { calculables = watchDataSource.getCalculable(); } CompositeType type = JMXUtil.createCompositeType(JMXUtil.toMap(calculables[0]), "Calculable", "Calculable"); TabularType tabularType = new TabularType("Calculables", "Calculables", type, new String[]{"when"}); TabularDataSupport tabularDataSupport = new TabularDataSupport(tabularType); for (Calculable calculable : calculables) { CompositeData compositeData = new CompositeDataSupport(type, JMXUtil.toMap(calculable)); tabularDataSupport.put(compositeData); } return tabularDataSupport; } catch (OpenDataException e) { logger.warn(e.toString(), e); } catch (IntrospectionException e) { logger.warn(e.toString(), e); } catch (IllegalAccessException e) { logger.warn(e.toString(), e); } catch (InvocationTargetException e) { logger.warn(e.toString(), e); } catch (RemoteException e) { logger.warn(e.toString(), e); } return null; } /** * @see WatchMBean#clear */ public void clear(){ if(localRef != null) { localRef.clear(); } else { try { watchDataSource.clear(); } catch (RemoteException e) { logger.warn(e.toString(), e); } } } /** * Add a watch record to the history * * @param calculable the Calculable record to be added */ public void addWatchRecord(Calculable calculable) { if(calculable!=null && dataLogger.isDebugEnabled()) dataLogger.debug("{}", calculable.toString()); /* Try direct reference first */ if(localRef != null) { localRef.addCalculable(calculable); return; } /* Use proxy */ if(watchDataSource == null) { logger.warn("WatchDataSource is null for Watch {}", getId()); return; } try { watchDataSource.addCalculable(calculable); } catch(RemoteException e) { logger.warn("WatchDataSource not available for Watch={}", getId(), e); } } /** * Indicates whether some other object is "equal to" this one. * * @param obj the object to compare to this one * @return true if the objects are equal */ public boolean equals(Object obj) { if(obj instanceof Watch) { if(getId() == null && ((Watch)obj).getId() == null) return (true); else if(getId() == null || ((Watch)obj).getId() == null) return (false); else return (getId().equals(((Watch)obj).getId())); } return (false); } /** * Returns a hash code value for the object. * * @return a hash code value for the object. */ public int hashCode() { int hc = 17; hc = 37*hc+(id != null? id.hashCode() : 0); return (hc); } /** * Returns a string representation of the object. * * @return a string representation of the object. */ public String toString() { return (id == null ? "null" : id); } }