/*=============================================================================*
* Copyright 2006 The Apache Software Foundation
*
* 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.apache.muse.ws.dm.muws.impl;
import java.util.Date;
import javax.xml.namespace.QName;
import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.util.xml.XsdUtils;
import org.apache.muse.ws.dm.muws.Metric;
import org.apache.muse.ws.dm.muws.MuwsConstants;
import org.apache.muse.ws.resource.WsResource;
import org.apache.muse.ws.resource.basefaults.BaseFault;
import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
/**
*
* SimpleMetric is a collection of metadata that is associated with resource
* properties that are also metrics. This information should be provided
* by a property's RMD definition, and can be used by a resource implementation
* to set up the collection and retrieval of a metric. The only way that this
* class can be used to modify a metric property is through the reset(Object)
* method - all other methods manipulate the metric's metadata, but not its
* actual value.
*
* @author Dan Jemiolo (danj)
*
*/
public class SimpleMetric implements Metric
{
private static Messages _MESSAGES = MessagesFactory.get(SimpleMetric.class);
//
// The metric attribute values
//
private int _changeType;
private int _gatheringTime;
private String _group = null;
//
// True if the metric property has not been modified since it's last reset.
//
private boolean _hasBeenReset = false;
//
// The calculation interval is optional - if not used, it's value is -1.
//
private long _interval = -1;
private String _intervalString = null;
private Date _lastUpdated = null;
private QName _name = null;
private Date _resetAt = null;
//
// The WS-resource that exposes the metric
//
private WsResource _resource = null;
private int _timeScope;
/**
*
* @param name
* The name of the metric property.
*
* @param resource
* The WS-resource that defines this metric.
*
*/
public SimpleMetric(QName name, WsResource resource)
{
if (name == null)
throw new NullPointerException(_MESSAGES.get("NullMetricName"));
if (resource == null)
throw new NullPointerException(_MESSAGES.get("NullResource"));
_name = name;
_resource = resource;
//
// get the metadata for the metric
//
ResourcePropertyCollection props = _resource.getPropertyCollection();
MetadataDescriptor metadata = props.getMetadata();
if (!metadata.isReadOnlyExternal(name))
{
Object[] filler = { name };
throw new RuntimeException(_MESSAGES.get("NotReadOnly", filler));
}
String change = metadata.getExtendedMetadata(name, MuwsConstants.CHANGE_TYPE_QNAME);
String gathering = metadata.getExtendedMetadata(name, MuwsConstants.GATHERING_QNAME);
String time = metadata.getExtendedMetadata(name, MuwsConstants.TIME_SCOPE_QNAME);
//
// required values (will throw if values are invalid)
//
_changeType = getChangeType(change);
_gatheringTime = getGatheringTime(gathering);
_timeScope = getTimeScope(time);
//
// optional values
//
_intervalString = metadata.getExtendedMetadata(name, MuwsConstants.CALC_INTERVAL_QNAME);
if (_intervalString != null)
_interval = XsdUtils.getDuration(_intervalString);
_group = metadata.getExtendedMetadata(name, MuwsConstants.METRIC_GROUP_QNAME);
//
// sanity check: if it's an Interval, it needs... an interval!
//
if (isInterval() != (getIntervalString() != null))
{
Object[] filler = { name };
throw new RuntimeException(_MESSAGES.get("InvalidIntervalDef", filler));
}
}
private int getChangeType(String value)
{
if (value.equals(MuwsConstants.COUNTER))
return COUNTER;
else if (value.equals(MuwsConstants.GAUGE))
return GAUGE;
else if (value.equals(MuwsConstants.UNKNOWN))
return UNKNOWN;
Object[] filler = { value };
throw new RuntimeException(_MESSAGES.get("InvalidChangeType", filler));
}
public String getDuration()
{
return _intervalString;
}
private int getGatheringTime(String value)
{
if (value.equals(MuwsConstants.ON_CHANGE))
return ON_CHANGE;
else if (value.equals(MuwsConstants.ON_DEMAND))
return ON_DEMAND;
else if (value.equals(MuwsConstants.PERIODIC))
return PERIODIC;
else if (value.equals(MuwsConstants.UNKNOWN))
return UNKNOWN;
Object[] filler = { value };
throw new RuntimeException(_MESSAGES.get("InvalidGatheringTime", filler));
}
public String getGroup()
{
return _group;
}
public long getInterval()
{
return _interval;
}
public String getIntervalString()
{
return _intervalString;
}
public Date getLastUpdated()
{
return _lastUpdated;
}
public QName getName()
{
return _name;
}
public Date getResetAt()
{
return _resetAt;
}
private int getTimeScope(String value)
{
if (value.equals(MuwsConstants.INTERVAL))
return INTERVAL;
else if (value.equals(MuwsConstants.POINT_IN_TIME))
return POINT_IN_TIME;
else if (value.equals(MuwsConstants.SINCE_RESET))
return SINCE_RESET;
Object[] filler = { value };
throw new RuntimeException(_MESSAGES.get("InvalidTimeScope", filler));
}
public WsResource getWsResource()
{
return _resource;
}
public boolean hasBeenReset()
{
return _hasBeenReset;
}
public boolean isCounter()
{
return _changeType == COUNTER;
}
public boolean isGauge()
{
return _changeType == GAUGE;
}
public boolean isInterval()
{
return _timeScope == INTERVAL;
}
public boolean isOnChange()
{
return _gatheringTime == ON_CHANGE;
}
public boolean isOnDemand()
{
return _gatheringTime == ON_DEMAND;
}
public boolean isPeriodic()
{
return _gatheringTime == PERIODIC;
}
public boolean isPointInTime()
{
return _timeScope == POINT_IN_TIME;
}
public boolean isSinceReset()
{
return _timeScope == SINCE_RESET;
}
public void reset(Object value)
throws BaseFault
{
if (isPointInTime())
{
Object[] filler = { getName() };
throw new IllegalStateException(_MESSAGES.get("ResetNotAllowed", filler));
}
//
// this call will eventually result in a listener calling the
// update() method below - we will then overwrite the values
// of the date attributes
//
ResourcePropertyCollection props = getWsResource().getPropertyCollection();
props.updateResourceProperty(getName(), new Object[]{ value });
_resetAt = new Date();
_lastUpdated = null;
_hasBeenReset = true;
}
public void update()
{
_lastUpdated = new Date();
_hasBeenReset = false;
}
}