/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002, 2010 Oracle and/or its affiliates. All rights reserved.
*
*/
package com.sleepycat.persist.evolve;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.StoreConfig;
/**
* A collection of mutations for configuring class evolution.
*
*
Mutations are configured when a store is opened via {@link
* StoreConfig#setMutations StoreConfig.setMutations}. For example:
*
*
* Mutations mutations = new Mutations();
* // Add mutations...
* StoreConfig config = new StoreConfig();
* config.setMutations(mutations);
* EntityStore store = new EntityStore(env, "myStore", config);
*
* Mutations cause data conversion to occur lazily as instances are read
* from the store. The {@link EntityStore#evolve EntityStore.evolve} method
* may also be used to perform eager conversion.
*
* Not all incompatible class changes can be handled via mutations. For
* example, complex refactoring may require a transformation that manipulates
* multiple entity instances at once. Such changes are not possible with
* mutations but can made by performing a store conversion.
*
* @see com.sleepycat.persist.evolve Class Evolution
* @author Mark Hayes
*/
public class Mutations implements Serializable {
private static final long serialVersionUID = -1744401530444812916L;
private Map renamers;
private Map deleters;
private Map converters;
/**
* Creates an empty set of mutations.
*/
public Mutations() {
renamers = new HashMap();
deleters = new HashMap();
converters = new HashMap();
}
/**
* Returns true if no mutations are present.
*/
public boolean isEmpty() {
return renamers.isEmpty() &&
deleters.isEmpty() &&
converters.isEmpty();
}
/**
* Adds a renamer mutation.
*/
public void addRenamer(Renamer renamer) {
renamers.put(new Key(renamer), renamer);
}
/**
* Returns the renamer mutation for the given class, version and field, or
* null if none exists. A null field name should be specified to get a
* class renamer.
*/
public Renamer getRenamer(String className,
int classVersion,
String fieldName) {
return renamers.get(new Key(className, classVersion, fieldName));
}
/**
* Returns an unmodifiable collection of all renamer mutations.
*/
public Collection getRenamers() {
return renamers.values();
}
/**
* Adds a deleter mutation.
*/
public void addDeleter(Deleter deleter) {
deleters.put(new Key(deleter), deleter);
}
/**
* Returns the deleter mutation for the given class, version and field, or
* null if none exists. A null field name should be specified to get a
* class deleter.
*/
public Deleter getDeleter(String className,
int classVersion,
String fieldName) {
return deleters.get(new Key(className, classVersion, fieldName));
}
/**
* Returns an unmodifiable collection of all deleter mutations.
*/
public Collection getDeleters() {
return deleters.values();
}
/**
* Adds a converter mutation.
*/
public void addConverter(Converter converter) {
converters.put(new Key(converter), converter);
}
/**
* Returns the converter mutation for the given class, version and field,
* or null if none exists. A null field name should be specified to get a
* class converter.
*/
public Converter getConverter(String className,
int classVersion,
String fieldName) {
return converters.get(new Key(className, classVersion, fieldName));
}
/**
* Returns an unmodifiable collection of all converter mutations.
*/
public Collection getConverters() {
return converters.values();
}
private static class Key extends Mutation {
static final long serialVersionUID = 2793516787097085621L;
Key(String className, int classVersion, String fieldName) {
super(className, classVersion, fieldName);
}
Key(Mutation mutation) {
super(mutation.getClassName(),
mutation.getClassVersion(),
mutation.getFieldName());
}
}
/**
* Returns true if this collection has the same set of mutations as the
* given collection and all mutations are equal.
*/
@Override
public boolean equals(Object other) {
if (other instanceof Mutations) {
Mutations o = (Mutations) other;
return renamers.equals(o.renamers) &&
deleters.equals(o.deleters) &&
converters.equals(o.converters);
} else {
return false;
}
}
@Override
public int hashCode() {
return renamers.hashCode() +
deleters.hashCode() +
converters.hashCode();
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
if (renamers.size() > 0) {
buf.append(renamers.values());
}
if (deleters.size() > 0) {
buf.append(deleters.values());
}
if (converters.size() > 0) {
buf.append(converters.values());
}
if (buf.length() > 0) {
return buf.toString();
} else {
return "[Empty Mutations]";
}
}
}