/**
* Copyright (C) 2008 Progress Software, Inc. All rights reserved.
* http://fusesource.com
*
* The software in this package is published under the terms of the AGPL license
* a copy of which has been included with this distribution in the license.txt file.
*/
package org.fusesource.cloudmix.common.dto;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @version $Revision$
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ProvisioningHistory {
private static final transient Log LOG = LogFactory.getLog(ProvisioningHistory.class);
@XmlElement(name = "config")
private List<AgentCfgUpdate> cfgUpdates = new ArrayList<AgentCfgUpdate>();
@XmlElement(name = "actions")
private List<ProvisioningAction> actions = new ArrayList<ProvisioningAction>();
private Date lastModified;
@XmlTransient
private String digest;
@XmlTransient
private long updateCounter;
@Override
public String toString() {
return "ProvisioningHistory[" + cfgUpdates + " " + actions + "]";
}
public void addAction(ProvisioningAction action) {
actions.add(action);
onUpdated();
LOG.debug("Added action: " + action);
}
public boolean removeAction(ProvisioningAction action) {
boolean answer = actions.remove(action);
onUpdated();
return answer;
}
public void addCfgUpdate(AgentCfgUpdate anUpdate) {
synchronized (cfgUpdates) {
doRemoveCfgUpdate(anUpdate.getProperty());
cfgUpdates.add(anUpdate);
onUpdated();
LOG.debug("Added configuration update: " + anUpdate);
}
}
public boolean removeCfgUpdate(AgentCfgUpdate anUpdate) {
synchronized (cfgUpdates) {
boolean answer = cfgUpdates.remove(anUpdate);
onUpdated();
return answer;
}
}
public boolean removeCfgUpdate(String aPropName) {
synchronized (cfgUpdates) {
return doRemoveCfgUpdate(aPropName);
}
}
private boolean doRemoveCfgUpdate(String aPropName) {
if (aPropName == null || aPropName.trim().length() == 0) {
return false;
}
for (AgentCfgUpdate anUpdate : cfgUpdates) {
if (aPropName.equals(anUpdate.getProperty())) {
boolean answer = cfgUpdates.remove(anUpdate);
onUpdated();
return answer;
}
}
return false;
}
public void populate(ProcessList processList) {
Process process = processList.process();
for (ProvisioningAction action : actions) {
if (action.isInstall()) {
process.feature(action.getFeature(), action.getResource());
}
}
}
public void populate(Set<String> features) {
for (ProvisioningAction action : actions) {
if (action.isInstall()) {
if (action.getFeature() == null) {
throw new IllegalArgumentException("action.getFeature() should not be null");
}
features.add(action.getFeature());
}
}
}
// Fluent API
//-------------------------------------------------------------------------
public ProvisioningHistory install(String featureId, String featureUrl) {
addAction(new ProvisioningAction(featureId, featureUrl));
return this;
}
// Properties
//-------------------------------------------------------------------------
public List<ProvisioningAction> getActions() {
return actions;
}
public void setActions(List<ProvisioningAction> actions) {
onUpdated();
this.actions = actions;
}
public List<AgentCfgUpdate> getCfgUpdates() {
return cfgUpdates;
}
public void setCfgUpdates(List<AgentCfgUpdate> someUpdates) {
onUpdated();
cfgUpdates = someUpdates;
}
public String getDigest() {
if (digest == null) {
digest = createDigest();
}
return digest;
}
public Date getLastModified() {
if (lastModified == null) {
onUpdated();
}
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
// Implementation methods
//-------------------------------------------------------------------------
protected void onUpdated() {
lastModified = new Date();
digest = null;
++updateCounter;
}
/**
* Lets calculate a digest using the hash codes of the configuration updates, the actions, the last
* modified time and an update counter
*/
protected String createDigest() {
long hash = updateCounter;
for (ConfigurationUpdate update : cfgUpdates) {
hash *= 3;
hash += update.hashCode();
}
for (ProvisioningAction action : actions) {
hash *= 3;
hash += action.hashCode();
}
hash ^= getLastModified().getTime();
return "" + hash;
}
}