/*
 * $Header: /home/cvspublic/jakarta-slide/projector/src/java/org/apache/slide/projector/expression/EventExpression.java,v 1.6 2004/11/28 13:54:09 dflorey Exp $
 * $Revision: 1.6 $
 * $Date: 2004/11/28 13:54:09 $
 *
 * ====================================================================
 *
 * Copyright 1999-2002 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.slide.projector.expression;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.xmlio.out.XMLStringWriter;
import org.apache.commons.xmlio.out.XMLWriter;
import org.apache.slide.projector.Projector;
import org.apache.slide.projector.engine.Job;
import org.apache.slide.projector.engine.Scheduler;
import org.apache.slide.projector.repository.RepositoryException;
import org.apache.slide.projector.value.URIValue;
import org.apache.webdav.lib.Subscriber;

/**
 * The EventExpression class
 * 
 */
public class EventExpression implements Expression, Subscriber {
    private final static Logger logger = Logger.getLogger(EventExpression.class.getName());

	public final static String URI = "uri";
	public final static String DEPTH = "depth";
	
	private String method;
    private Map properties = new HashMap();
    private boolean eval = false;
    private Job job;

    public EventExpression(String method) {
        this.method = method;
    }

    public void addProperty(String key, String value) {
    	properties.put(key, value);
    }
    
    public Expression activate(Job job) {
    	EventExpression activatedExpression = new EventExpression(method);
    	activatedExpression.setJob(job);
    	activatedExpression.properties.putAll(properties);
    	String uri = (String)properties.get(URI);
    	int depth = 0;
    	String depthProperty = (String)properties.get(DEPTH);
    	if ( depthProperty != null ) {
    		depth = Integer.valueOf(depthProperty).intValue(); 
    	}
    	try {
    	    Projector.getRepository().subscribe(method, new URIValue(uri), depth, activatedExpression, Projector.getCredentials());
    	} catch ( RepositoryException exception ) {
    	    logger.log(Level.SEVERE, "Failed to subscribe listener on Uri'"+uri+"'", exception);
    	}
    	return activatedExpression;
    }

    public void setJob(Job job) {
    	this.job = job;
    }
    
    public boolean evaluate() {
        return eval;
    }

    public void save(XMLStringWriter writer) {
        if ( eval ) {
            new TrueExpression().save(writer);
        } else {
            writer.writeStartTag(XMLWriter.createStartTag("event", "method", method));
            for ( Iterator i = properties.entrySet().iterator(); i.hasNext(); ) {
            	Map.Entry entry = (Map.Entry)i.next();
            	writer.writeEmptyElement(XMLWriter.createEmptyTag("property", new String[] { "key", "value" }, new String[] { (String)entry.getKey(), (String)entry.getValue() }));
            }
            writer.writeEndTag(XMLWriter.createEndTag("event"));
        }
    }

	public void notify(String uri, Map information) {
		eval = true;
		try {
		    Projector.getRepository().unsubscribe(new URIValue((String)properties.get(URI)), this, Projector.getCredentials());
		} catch ( RepositoryException exception ) {
		    logger.log(Level.SEVERE, "Failed to unsubscribe listener on Uri'"+uri+"'", exception);
		}
		Scheduler.getInstance().notify(job);
    }
}