/////////////////////////////////////////////////////////////////////////
//
// © Institute for Software Science, University of Vienna, 2004
//
// Copyright in this software belongs to Institute for Software Science, 
// University of Vienna, Nordbergstrasse 15/C/3, 1090 Vienna, Austria
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//	Created By :		Nikolay Terziev
//	Created Date :		2004/04/20
//	Created for Project:	GEMSS
//
////////////////////////////////////////////////////////////////////////
//
// Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//	Last commit info:	$Author: niki $
//					$Date: 2004/12/16 12:25:19 $
//					$Revision: 1.7 $
//
/////////////////////////////////////////////////////////////////////////

package at.ac.univie.iss.descriptors.qos;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
import java.util.logging.Logger;
import java.util.logging.Level;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

import at.ac.univie.iss.descriptors.qos.jaxb.qosdesc.*;

/**
*	A <code>QoSDescriptorImpl</code> is an XML document representing a
*	(potential) agreement about one job execution between a service consumer
*	(client) and a service provider following the Web Service Level Agreement
*	(WSLA) specification. <p>
*	A <code>QoSDescriptorImpl</code> is an implementation of the <code>
*	QoSDescriptor</code> which represents an XML QoS Descriptor in Java.
*	Internally this class uses JAXB to access the content of the XML QoS
*	Descriptor.
*
*	@author Gerhard Engelbrecht
*	@author Nikolay Terziev
*/
public class QoSDescriptorImpl implements QoSDescriptor {

	private static Logger logger = Logger.getLogger("at.ac.univie.iss.descriptors.qos");

	final private String PRICE_OBJECTIVE_STR = new String("priceObjective");
	final private String START_JOB_OBJECTIVE_STR = new String("startJobObjective");
	final private String END_JOB_OBJECTIVE_STR = new String("endJobObjective");

    private SLA sla = null;

    private Unmarshaller unmarshaller = null;
    private Marshaller   marshaller = null;
    private ObjectFactory objFactory = null;
    private JAXBContext jc;

    /**
    *	Creates a new emtpy QoS Descriptor.
    */
    public QoSDescriptorImpl() throws Exception {

        try {
            jc = JAXBContext.newInstance("at.ac.univie.iss.descriptors.qos.jaxb.qosdesc");

            unmarshaller = jc.createUnmarshaller();
            unmarshaller.setValidating(true);

            marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            objFactory = new ObjectFactory();

            sla = objFactory.createSLA();
            sla.setName("SLA NAME");
            sla.setParties(createPartiesType("", ""));

            ServiceDefinitionType serviceDefinitionType = createServiceDefinitionType("SPECTService");

// The Schedule  tag is removed
/*
            ScheduleType scheduleType = createScheduleType("OverallContractDuration");

            Calendar nextMonth = Calendar.getInstance();

            nextMonth.set(nextMonth.get(Calendar.YEAR), nextMonth.get(Calendar.MONTH) + 1, nextMonth.get(Calendar.DATE));


            scheduleType.setInterval(createIntervalType());
            scheduleType.setPeriod(createPeriodType(Calendar.getInstance(), nextMonth));
            serviceDefinitionType.setSchedule(scheduleType);
*/
            serviceDefinitionType.getSLAParameter().add(createSLAParameterType(PRICE_OBJECTIVE_STR, "double", "euro", "priceMetric"));

            MetricType metricType = createMetricType("priceMetric", "double", "euro", "ISS");

            metricType.setMeasurementDirective(createGauge("", "double"));
            serviceDefinitionType.getMetric().add(metricType);

            // Operation
            WSDLSOAPOperationDescriptionType wsdlOprDsc = createWSDLSOAPOperationDescriptionType("getCid", "",
                    "SOAPNotificationBinding", "getCid");

            serviceDefinitionType.getOperation().add(wsdlOprDsc);

            wsdlOprDsc = createWSDLSOAPOperationDescriptionType("upload", "", "SOAPNotificationBinding", "upload");
            serviceDefinitionType.getOperation().add(wsdlOprDsc);

            wsdlOprDsc = createWSDLSOAPOperationDescriptionType("start", "", "SOAPNotificationBinding", "start");
            wsdlOprDsc.getSLAParameter().add(createSLAParameterType("beginTime", "time", "GMT", "runTimeMetric"));
            wsdlOprDsc.getSLAParameter().add(createSLAParameterType("endTime", "time", "GMT", "endTimeMetric"));
            metricType = createMetricType("beginTimeMetric", "time", "GMT", "ISS");
            metricType.setMeasurementDirective(createGauge("", "time"));
            wsdlOprDsc.getMetric().add(metricType);
            metricType = createMetricType("endTimeMetric", "time", "GMT", "ISS");
            metricType.setMeasurementDirective(createGauge("", "time"));
            wsdlOprDsc.getMetric().add(metricType);
            serviceDefinitionType.getOperation().add(wsdlOprDsc);

            wsdlOprDsc = createWSDLSOAPOperationDescriptionType("getStatus", "", "SOAPNotificationBinding", "getStatus");
            serviceDefinitionType.getOperation().add(wsdlOprDsc);

            wsdlOprDsc = createWSDLSOAPOperationDescriptionType("download", "", "SOAPNotificationBinding", "download");
            serviceDefinitionType.getOperation().add(wsdlOprDsc);

            wsdlOprDsc = createWSDLSOAPOperationDescriptionType("acknowledgeResults", "", "SOAPNotificationBinding",
                    "acknowledgeResults");
            serviceDefinitionType.getOperation().add(wsdlOprDsc);

            sla.setServiceDefinition(serviceDefinitionType);

            // Obligations
            ObligationsType obligations = createObligationsType();

            ServiceLevelObjectiveType serviceLevel = createServiceLevelObjectiveType(PRICE_OBJECTIVE_STR);

            serviceLevel.setObliged("provider");
            PeriodType period = createPeriodType(Calendar.getInstance(), Calendar.getInstance());

            serviceLevel.setValidity(period);
            Equal equal = createEqual(0, PRICE_OBJECTIVE_STR);
            LogicExpressionType logic = createLogicExpressionType(equal);

            serviceLevel.setExpression(logic);
            serviceLevel.setEvaluationEvent("NewValue");
            obligations.getServiceLevelObjective().add(serviceLevel);

            serviceLevel = createServiceLevelObjectiveType(START_JOB_OBJECTIVE_STR);
            serviceLevel.setObliged("provider");
            period = createPeriodType(Calendar.getInstance(), Calendar.getInstance());
            serviceLevel.setValidity(period);
            GreaterEqual greaterEqual = createGreaterEqual(0, "startTime");

            logic = createLogicExpressionType(greaterEqual);
            serviceLevel.setExpression(logic);
            serviceLevel.setEvaluationEvent("NewValue");
            obligations.getServiceLevelObjective().add(serviceLevel);

            serviceLevel = createServiceLevelObjectiveType(END_JOB_OBJECTIVE_STR);
            serviceLevel.setObliged("provider");
            period = createPeriodType(Calendar.getInstance(), Calendar.getInstance());
            serviceLevel.setValidity(period);
            LessEqual lessEqual = createLessEqual(0, "endTime");

            logic = createLogicExpressionType(lessEqual);
            serviceLevel.setExpression(logic);
            serviceLevel.setEvaluationEvent("NewValue");
            obligations.getServiceLevelObjective().add(serviceLevel);

            sla.setObligations(obligations);

        } catch (JAXBException je) {

        	logger.log(Level.SEVERE, "An error occured while creating a new QoS Descriptor (see details below)!", je);
            throw je;
        }

    }

	/**
	*	Creates a QoS Descriptor based on the given XML-based document.
	*/
    public QoSDescriptorImpl(String sSla) throws Exception {

        try {

            jc = JAXBContext.newInstance("at.ac.univie.iss.descriptors.qos.jaxb.qosdesc");

            unmarshaller = jc.createUnmarshaller();
            unmarshaller.setValidating(true);

            marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            objFactory = new ObjectFactory();

            sla = (SLA) unmarshaller.unmarshal(new StreamSource(new StringReader(sSla)));

        } catch (UnmarshalException ue) {

        	logger.log(Level.SEVERE, "An error occured while creating a new QoS Descriptor based on a given String (see details below)!", ue);
        	throw ue;

        } catch (JAXBException je) {

        	logger.log(Level.SEVERE, "An error occured while creating a new QoS Descriptor based on a given String (see details below)!", je);
        	throw je;

        } catch (Exception e) {

        	logger.log(Level.SEVERE, "An error occured while creating a new QoS Descriptor based on a given String (see details below)!", e);
        	throw e;
        }
    }

    public void setSLAName(String slaName){

        if (sla !=null){

            sla.setName(slaName);
        }
    }

    public String getSLAName(){

         if (sla !=null){

            return sla.getName();
        }

        return null;
    }

    public void setProviderName(String providerName)throws Exception {

        PartiesType parties = sla.getParties();

        if (parties != null) {

            SignatoryPartyType  signatory = parties.getServiceProvider();

            if (signatory != null) {
                signatory.setName(providerName);

                return;
            }
        }
        throw new Exception("The parties type is not set (null).");
    }

    public String getProviderName() {

        PartiesType parties = sla.getParties();

        if (parties != null) {

            SignatoryPartyType  signatory = parties.getServiceProvider();

            if (signatory != null) {
                return signatory.getName();
            }
        }

        return null;
    }

    public void setConsumerName(String consumerName)throws Exception {

        PartiesType parties = sla.getParties();

        if (parties != null) {

            SignatoryPartyType  signatory = parties.getServiceConsumer();

            if (signatory != null) {
                signatory.setName(consumerName);

                return;
            }
        }
        throw new Exception(" The consumer is not set");
    }

    public String getConsumerName() {

        PartiesType parties = sla.getParties();

        if (parties != null) {

            SignatoryPartyType  signatory = parties.getServiceConsumer();

            if (signatory != null) {
                return signatory.getName();
            }
        }

        return null;
    }

    public void setObjectivePrice(double price) throws Exception {

        ObligationsType obligations = sla.getObligations();

        if (obligations != null) {

            List objectives = obligations.getServiceLevelObjective();

            Iterator iter = objectives.iterator();

            while (iter.hasNext()) {

                ServiceLevelObjectiveType objective = (ServiceLevelObjectiveType) iter.next();

                if (objective.getName().equals(PRICE_OBJECTIVE_STR)) {

               		String slaParam = ((Equal)objective.getExpression().getPredicate()).getSLAParameter();

                    Equal equal = createEqual(price, slaParam);

                    LogicExpressionType logic = createLogicExpressionType(equal);

                    objective.setExpression(logic);

                    return;
                }
            }
        }
    }

    public double getObjectivePrice() {

        ObligationsType obligations = sla.getObligations();

        if (obligations != null) {

            List objectives = obligations.getServiceLevelObjective();

            Iterator iter = objectives.iterator();

            while (iter.hasNext()) {

                ServiceLevelObjectiveType objective = (ServiceLevelObjectiveType) iter.next();

                if (objective.getName().equals(PRICE_OBJECTIVE_STR)) {

                    PredicateType predicate = objective.getExpression().getPredicate();

                    if (predicate instanceof Equal) {
                        return ((Equal) predicate).getValue();
                    }

                }
            }
        }
        return -1;
    }

    public void setObjectiveBeginTime(Calendar date) throws Exception {

        ObligationsType obligations = sla.getObligations();

        boolean isFound = false;
        Calendar endCalendar = Calendar.getInstance();

        if (obligations != null) {

            Calendar millenium = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

            millenium.clear();
            millenium.set(2000, 0, 1, 0, 0, 0);

            long resultMillis = date.getTimeInMillis() - millenium.getTimeInMillis();

            List objectives = obligations.getServiceLevelObjective();

            Iterator iter = objectives.iterator();

            while (iter.hasNext()) {

                ServiceLevelObjectiveType objective = (ServiceLevelObjectiveType) iter.next();

                PeriodType period = objective.getValidity();

                period.setStart(date);

                endCalendar = period.getEnd();

                if (objective.getName().startsWith((START_JOB_OBJECTIVE_STR))) {

                    isFound = true;

               		String slaParam = ((GreaterEqual)objective.getExpression().getPredicate()).getSLAParameter();

                    GreaterEqual greaterEqual = createGreaterEqual(resultMillis, slaParam); //"beginTime");

                    LogicExpressionType logic = createLogicExpressionType(greaterEqual);

                    objective.setExpression(logic);

                }
            }

            if (!isFound) {

                ServiceLevelObjectiveType serviceLevel = createServiceLevelObjectiveType(START_JOB_OBJECTIVE_STR);

                serviceLevel.setObliged("provider");

                PeriodType period = createPeriodType(date, endCalendar);

                serviceLevel.setValidity(period);

                GreaterEqual greaterEqual = createGreaterEqual(resultMillis, "startTime");
                LogicExpressionType logic = createLogicExpressionType(greaterEqual);

                serviceLevel.setExpression(logic);

                serviceLevel.setEvaluationEvent("NewValue");

                objectives.add(serviceLevel);
            }
        }
    }

    public Calendar getObjectiveBeginTime() {

        ObligationsType obligations = sla.getObligations();

        Calendar millenium = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

        millenium.clear();
        millenium.set(2000, 0, 1, 0, 0, 0);

        if (obligations != null) {

            List objectives = obligations.getServiceLevelObjective();

            Iterator iter = objectives.iterator();

            while (iter.hasNext()) {

                ServiceLevelObjectiveType objective = (ServiceLevelObjectiveType) iter.next();

                PeriodType period = objective.getValidity();

                if (objective.getName().startsWith((START_JOB_OBJECTIVE_STR))) {

                    PredicateType predicate = objective.getExpression().getPredicate();

                    if (predicate instanceof GreaterEqual) {

                        Calendar beginTime = Calendar.getInstance();

                        beginTime.clear();

                        beginTime.setTimeInMillis(((GreaterEqual) predicate).getValue() + millenium.getTimeInMillis());

                        return beginTime;
                    }
                }
            }
        }
        return null;
    }

    public void setObjectiveEndTime(Calendar date) throws Exception {

        ObligationsType obligations = sla.getObligations();

        boolean isFound = false;
        Calendar startCalendar = Calendar.getInstance();

        if (obligations != null) {

            Calendar millenium = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

            millenium.clear();
            millenium.set(2000, 0, 1, 0, 0, 0);

            long resultMillis = date.getTimeInMillis() - millenium.getTimeInMillis();

            List objectives = obligations.getServiceLevelObjective();

            Iterator iter = objectives.iterator();

            while (iter.hasNext()) {

                ServiceLevelObjectiveType objective = (ServiceLevelObjectiveType) iter.next();

                PeriodType period = objective.getValidity();

                period.setEnd(date);

                startCalendar = period.getStart();

                if (objective.getName().startsWith((END_JOB_OBJECTIVE_STR))) {

                    isFound = true;

               		String slaParam = ((LessEqual)objective.getExpression().getPredicate()).getSLAParameter();

                    LessEqual lessEqual = createLessEqual(resultMillis, slaParam); // "endTime");

                    LogicExpressionType logic = createLogicExpressionType(lessEqual);

                    objective.setExpression(logic);

                }
            }

            if (!isFound) {

                ServiceLevelObjectiveType serviceLevel = createServiceLevelObjectiveType(END_JOB_OBJECTIVE_STR);

                serviceLevel.setObliged("provider");

                PeriodType period = createPeriodType(startCalendar, date);

                serviceLevel.setValidity(period);

                LessEqual lessEqual = createLessEqual(resultMillis, "endTime");
                LogicExpressionType logic = createLogicExpressionType(lessEqual);

                serviceLevel.setExpression(logic);

                serviceLevel.setEvaluationEvent("NewValue");

                objectives.add(serviceLevel);
            }
        }
    }

    public Calendar getObjectiveEndTime() {

        ObligationsType obligations = sla.getObligations();

        Calendar millenium = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

        millenium.clear();
        millenium.set(2000, 0, 1, 0, 0, 0);

        if (obligations != null) {

            List objectives = obligations.getServiceLevelObjective();

            Iterator iter = objectives.iterator();

            while (iter.hasNext()) {

                ServiceLevelObjectiveType objective = (ServiceLevelObjectiveType) iter.next();

                PeriodType period = objective.getValidity();

                if (objective.getName().startsWith((END_JOB_OBJECTIVE_STR))) {

                    PredicateType predicate = objective.getExpression().getPredicate();

                    if (predicate instanceof LessEqual) {

                        Calendar endTime = Calendar.getInstance();

                        endTime.clear();

                        endTime.setTimeInMillis(((LessEqual) predicate).getValue() + millenium.getTimeInMillis());

                        return endTime;
                    }
                }
            }
        }
        return null;
    }

  	/**
  	* 	Returns an XML document of this QoS Descriptor as String.
  	*/
    public String toString() {

        StringWriter slaWriter = new StringWriter();

        try {

            marshaller.marshal(sla, slaWriter);

            return slaWriter.toString();

        } catch (javax.xml.bind.MarshalException me) {

        	logger.log(Level.SEVERE, "An error occured while transforming the QoS Descriptor to a String (see details below)!", me);

        } catch (JAXBException je) {

        	logger.log(Level.SEVERE, "An error occured while transforming the QoS Descriptor to a String (see details below)!", je);
        }
        return null;
    }

    // Create Methods

    private PartiesType createPartiesType(String serviceProvider, String serviceConsumer)throws JAXBException {

        PartiesType parties = objFactory.createPartiesType();

        parties.setServiceProvider(createSignatoryPartyType(serviceProvider));
        parties.setServiceConsumer(createSignatoryPartyType(serviceConsumer));

        return parties;
    }

    private SignatoryPartyType createSignatoryPartyType(String name)throws JAXBException {

        SignatoryPartyType  signatory;

        signatory = objFactory.createSignatoryPartyType();
        signatory.setName(name);

        return signatory;
    }

    private ServiceDefinitionType createServiceDefinitionType(String name) throws JAXBException {

        ServiceDefinitionType serviceDefinition = objFactory.createServiceDefinitionType();

        serviceDefinition.setName(name);

        return serviceDefinition;
    }

/*
    private ScheduleType createScheduleType(String name) throws JAXBException {

        ScheduleType schedule = objFactory.createScheduleType();

        schedule.setName(name);

        return schedule;
    }

    private IntervalType createIntervalType() throws JAXBException {

        IntervalType interval = objFactory.createIntervalType();

        interval.setMonths(java.math.BigInteger.ONE);

        return interval;
    }
*/
    private SLAParameterType createSLAParameterType(String name, String type, String unit, String metric) throws JAXBException {

        SLAParameterType sLAParameterType = objFactory.createSLAParameterType();

        sLAParameterType.setMetric(metric);
        sLAParameterType.setName(name);
        sLAParameterType.setUnit(unit);
        sLAParameterType.setType(type);

        return sLAParameterType;
    }

    private MetricType createMetricType(String name, String type, String unit, String source) throws JAXBException {

        MetricType metricType = objFactory.createMetricType();

        metricType.setName(name);
        metricType.setUnit(unit);
        metricType.setType(type);
        metricType.setSource(source);

        return metricType;
    }

    private Gauge createGauge(String measurementURI, String resultType) throws JAXBException {

        Gauge gauge = objFactory.createGauge();

        gauge.setMeasurementURI(measurementURI);
        gauge.setResultType(resultType);

        return gauge;
    }

    private ObligationsType createObligationsType() throws JAXBException {

        ObligationsType obli = objFactory.createObligationsType();

        return obli;
    }

    private WSDLSOAPOperationDescriptionType createWSDLSOAPOperationDescriptionType(String name, String wsdlFile, String sOAPBindingName, String sOAPOperationName) throws JAXBException {

        WSDLSOAPOperationDescriptionType wsdlOpr = objFactory.createWSDLSOAPOperationDescriptionType();

        wsdlOpr.setName(name);
        wsdlOpr.setWSDLFile(wsdlFile);
        wsdlOpr.setSOAPBindingName(sOAPBindingName);
        wsdlOpr.setSOAPOperationName(sOAPOperationName);

        return wsdlOpr;
    }

    private ServiceLevelObjectiveType createServiceLevelObjectiveType(String name) throws JAXBException {

        ServiceLevelObjectiveType serviceLevel = objFactory.createServiceLevelObjectiveType();

        serviceLevel.setName(name);

        return serviceLevel;
    }

    private PeriodType createPeriodType(Calendar start, Calendar end) throws JAXBException {

        PeriodType periodType = objFactory.createPeriodType();

        periodType.setStart(start);
        periodType.setEnd(end);

        return periodType;
    }

    private LogicExpressionType createLogicExpressionType(PredicateType value) throws JAXBException {

        LogicExpressionType logic = objFactory.createLogicExpressionType();

        logic.setPredicate(value);

        return logic;
    }

    private Equal createEqual(double value, String  slaParameter) throws JAXBException {

        Equal equal = objFactory.createEqual();

        equal.setSLAParameter(slaParameter);

        equal.setValue(value);

        return equal;
    }

    private LessEqual createLessEqual(long value, String  slaParameter) throws JAXBException {

        LessEqual lessEqual = objFactory.createLessEqual();

        lessEqual.setSLAParameter(slaParameter);

        lessEqual.setValue(value);

        return lessEqual;
    }

    private GreaterEqual createGreaterEqual(long value, String  slaParameter) throws JAXBException {

        GreaterEqual greaterEqual = objFactory.createGreaterEqual();

        greaterEqual.setSLAParameter(slaParameter);

        greaterEqual.setValue(value);

        return greaterEqual;
    }

	/**
	*	Tests if the given QoS Descriptor is equal to this QoS Descriptor.
	*	<p>
	*	Currently only the SLA name, the provider, the consumer, the objective
	*	price, the objective begin time and the objective end time have to be
	*	equal of both descriptors.
	*
	*/
    public boolean equals(Object qosDesc) {

    	if ((qosDesc != null) &&
    		(qosDesc instanceof QoSDescriptor) &&
    		(((QoSDescriptor)qosDesc).getSLAName().equals(this.getSLAName())) &&
    		(((QoSDescriptor)qosDesc).getProviderName().equals(this.getProviderName())) &&
    		(((QoSDescriptor)qosDesc).getConsumerName().equals(this.getConsumerName())) &&
    		(((QoSDescriptor)qosDesc).getObjectivePrice() == (this.getObjectivePrice())) &&
    		(((QoSDescriptor)qosDesc).getObjectiveBeginTime().equals(this.getObjectiveBeginTime())) &&
    		(((QoSDescriptor)qosDesc).getObjectiveEndTime().equals(this.getObjectiveEndTime()))
    		) {
				return true;
    	}


		try {
	    	if (qosDesc == null) {

	        	logger.log(Level.FINE, "Equals check: Given qosDesc is null!\n");
	    	}
	    	if (!(qosDesc instanceof QoSDescriptor)){

	        	logger.log(Level.FINE, "Equals check: Given qosDesc is not an instance of QoSDescriptor!\n");
	    	}
	    	if (!(((QoSDescriptor)qosDesc).getSLAName().equals(this.getSLAName()))) {

	        	logger.log(Level.FINE, "Equals check: SLA name does not match!\n");
	    	}
	    	if (!(((QoSDescriptor)qosDesc).getProviderName().equals(this.getProviderName()))) {

	        	logger.log(Level.FINE, "Equals check: Provider name does not match!\n");
	    	}
	    	if (!(((QoSDescriptor)qosDesc).getConsumerName().equals(this.getConsumerName()))) {

	        	logger.log(Level.FINE, "Equals check: Consumer name does not match!\n");
	    	}
	    	if (!(((QoSDescriptor)qosDesc).getObjectivePrice() == (this.getObjectivePrice()))) {

	        	logger.log(Level.FINE, "Equals check: Objective price does not match!\n");
	    	}
	    	if (!(((QoSDescriptor)qosDesc).getObjectiveBeginTime().equals(this.getObjectiveBeginTime()))) {

	        	logger.log(Level.FINE, "Equals check: Objective begin time does not match!\n");
	    	}
	    	if (!(((QoSDescriptor)qosDesc).getObjectiveEndTime().equals(this.getObjectiveEndTime()))) {

	        	logger.log(Level.FINE, "Equals check: Objective end time does not match!\n");
			}
		}
		catch (Exception exception) {

        	logger.log(Level.FINE, "Equals check exception (see details below)!\n", exception);
		}
    	return false;
    }

}
