001: package liquibase.change.custom;
002:
003: import liquibase.change.AbstractChange;
004: import liquibase.database.Database;
005: import liquibase.database.sql.SqlStatement;
006: import liquibase.database.structure.DatabaseObject;
007: import liquibase.exception.CustomChangeException;
008: import liquibase.exception.RollbackImpossibleException;
009: import liquibase.exception.UnsupportedChangeException;
010: import liquibase.util.ObjectUtil;
011: import org.w3c.dom.Document;
012: import org.w3c.dom.Element;
013:
014: import java.util.*;
015:
016: /**
017: * Adapts CustomChange implementations to the standard change system used by LiquiBase.
018: * Custom change implementations should implement CustomSqlChange or CustomTaskChange
019: *
020: * @see liquibase.change.custom.CustomSqlChange
021: * @see liquibase.change.custom.CustomTaskChange
022: */
023: public class CustomChangeWrapper extends AbstractChange {
024:
025: private CustomChange customChange;
026: private String className;
027: private SortedSet<String> params = new TreeSet<String>();
028: private Map<String, String> paramValues = new HashMap<String, String>();
029: private ClassLoader classLoader;
030:
031: public CustomChangeWrapper() {
032: super ("customChange", "Custom Change");
033: }
034:
035: public CustomChange getCustomChange() {
036: return customChange;
037: }
038:
039: public ClassLoader getClassLoader() {
040: return classLoader;
041: }
042:
043: public void setClassLoader(ClassLoader classLoader) {
044: this .classLoader = classLoader;
045: }
046:
047: public void setClass(String className) throws CustomChangeException {
048: this .className = className;
049: try {
050: customChange = (CustomChange) Class.forName(className,
051: true, getClassLoader()).newInstance();
052: } catch (Exception e) {
053: throw new CustomChangeException(e);
054: }
055: }
056:
057: public void setParam(String name, String value) {
058: this .params.add(name);
059: this .paramValues.put(name, value);
060: }
061:
062: public SqlStatement[] generateStatements(Database database)
063: throws UnsupportedChangeException {
064: SqlStatement[] statements = null;
065: try {
066: configureCustomChange();
067: if (customChange instanceof CustomSqlChange) {
068: statements = ((CustomSqlChange) customChange)
069: .generateStatements(database);
070: } else if (customChange instanceof CustomTaskChange) {
071: ((CustomTaskChange) customChange).execute(database);
072: } else {
073: throw new UnsupportedChangeException(customChange
074: .getClass().getName()
075: + " does not implement "
076: + CustomSqlChange.class.getName()
077: + " or "
078: + CustomTaskChange.class.getName());
079: }
080: } catch (CustomChangeException e) {
081: throw new UnsupportedChangeException(e);
082: }
083:
084: if (statements == null) {
085: statements = new SqlStatement[0];
086: }
087: return statements;
088: }
089:
090: public SqlStatement[] generateRollbackStatements(Database database)
091: throws UnsupportedChangeException,
092: RollbackImpossibleException {
093: SqlStatement[] statements = null;
094: try {
095: configureCustomChange();
096: if (customChange instanceof CustomSqlRollback) {
097: statements = ((CustomSqlRollback) customChange)
098: .generateRollbackStatements(database);
099: } else if (customChange instanceof CustomTaskRollback) {
100: ((CustomTaskRollback) customChange).rollback(database);
101: } else {
102: throw new UnsupportedChangeException(
103: "Unknown rollback type: "
104: + customChange.getClass().getName());
105: }
106: } catch (CustomChangeException e) {
107: throw new UnsupportedChangeException(e);
108: }
109:
110: if (statements == null) {
111: statements = new SqlStatement[0];
112: }
113: return statements;
114:
115: }
116:
117: public boolean canRollBack() {
118: return customChange instanceof CustomSqlRollback
119: || customChange instanceof CustomTaskRollback;
120: }
121:
122: private void configureCustomChange() throws CustomChangeException {
123: try {
124: for (String param : params) {
125: ObjectUtil.setProperty(customChange, param, paramValues
126: .get(param));
127: }
128: customChange.setFileOpener(getFileOpener());
129: customChange.setUp();
130: } catch (Exception e) {
131: throw new CustomChangeException(e);
132: }
133: }
134:
135: public String getConfirmationMessage() {
136: return customChange.getConfirmationMessage();
137: }
138:
139: public Element createNode(Document currentChangeLogDOM) {
140: Element customElement = currentChangeLogDOM
141: .createElement("custom");
142: customElement.setAttribute("class", className);
143:
144: for (String param : params) {
145: Element paramElement = currentChangeLogDOM
146: .createElement("param");
147: paramElement.setAttribute("name", param);
148: paramElement.setAttribute("value", paramValues.get(param));
149:
150: customElement.appendChild(paramElement);
151: }
152:
153: return customElement;
154: }
155:
156: public Set<DatabaseObject> getAffectedDatabaseObjects() {
157: return null;
158: }
159: }
|