Java tutorial
/** * 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.jboss.loom.actions; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; import org.apache.commons.io.FileUtils; import org.jboss.loom.ex.ActionException; import org.jboss.loom.ex.MigrationException; import org.jboss.loom.spi.IMigrator; import org.jboss.loom.spi.ann.Property; import org.jboss.loom.utils.DirScanner; import org.jboss.loom.utils.Utils; /** * Base for file-based operations, like copying files, merging properties, or XSLT transformations. * * @author Ondrej Zizka, ozizka at redhat.com */ public abstract class FileAbstractAction extends AbstractStatefulAction { // First alternative: exact file. protected File src; // Second alternative: protected String pathMask; // What to look for - Ant-style path mask. protected File baseDir; // Where to look for. protected File dest; protected boolean failIfNotExist = true; private File temp; @Override public String toDescription() { return this.verb() + " file, " + addToDescription() + (this.failIfNotExist ? "" : " don't") + " fail if exists," + "\n from " + (this.src != null ? this.src.getPath() : this.pathMask) + "\n to " + (this.dest == null ? "null" : this.dest.getPath()); } protected abstract String verb(); protected String addToDescription() { return ""; } public FileAbstractAction(Class<? extends IMigrator> fromMigrator, File src, File dest) { super(fromMigrator); this.src = src; this.dest = dest; } public FileAbstractAction(Class<? extends IMigrator> fromMigrator, File src, File dest, boolean failIfNotExist) { super(fromMigrator); this.src = src; this.dest = dest; this.failIfNotExist = failIfNotExist; } public FileAbstractAction(Class<? extends IMigrator> fromMigrator, String pathMask, File baseDir, File dest, boolean failIfNotExist) { super(fromMigrator); this.src = null; this.baseDir = baseDir; this.pathMask = pathMask; this.dest = dest; this.failIfNotExist = failIfNotExist; } @Override public void preValidate() throws MigrationException { if (src != null) { if (!src.exists() && failIfNotExist) throw new ActionException(this, "File to " + verb().toLowerCase() + " doesn't exist: " + src.getPath()); } else if (this.pathMask == null) { throw new ActionException(this, "Neither src nor pathMask is set."); } // Copy multiple files to a file? else { // We would have to scan for the files now. } } /** * Copies the dest file, if it exists, to a temp file. */ @Override public void backup() throws MigrationException { if (!this.dest.exists()) return; try { this.temp = File.createTempFile(this.dest.getName(), null); FileUtils.deleteQuietly(this.temp); Utils.copyFileOrDirectory(this.dest, this.temp); } catch (IOException ex) { throw new ActionException(this, "Creating a backup file failed: " + ex.getMessage(), ex); } setState(IMigrationAction.State.BACKED_UP); } @Override public void rollback() throws MigrationException { if (!this.isAfterPerform()) return; // Delete the new file. FileUtils.deleteQuietly(this.dest); // Restore the backup file, if we created any. if (this.temp != null) { try { FileUtils.moveFile(this.temp, this.dest); } catch (IOException ex) { throw new ActionException(this, "Restoring the previous file failed: " + ex.getMessage(), ex); } } setState(IMigrationAction.State.ROLLED_BACK); } @Override public void postValidate() throws MigrationException { // Empty - JRE would give IOEx if something. } /** * Removes the temp file. */ @Override public void cleanBackup() { if (this.temp == null) return; if (this.temp.exists()) { FileUtils.deleteQuietly(this.temp); } setState(IMigrationAction.State.FINISHED); } //<editor-fold defaultstate="collapsed" desc="hash/eq - use src and dest."> @Override public int hashCode() { int hash = 7; hash = 67 * hash + Objects.hashCode(this.src); hash = 67 * hash + Objects.hashCode(this.dest); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final FileAbstractAction other = (FileAbstractAction) obj; if (!Objects.equals(this.src, other.src)) { return false; } if (!Objects.equals(this.dest, other.dest)) { return false; } return true; } //</editor-fold> @Property(name = "src", style = "code", label = "From") public File getSrc() { return src; } @Property(name = "dest", style = "code", label = "To") public File getDest() { return dest; } /** * Finds files according to this.pathMask and this.baseDir. */ private List<File> findFilesForPattern() throws IOException { if (this.pathMask == null) throw new IllegalStateException("pathMask is null in " + this.toDescription()); List<File> files = new DirScanner(this.pathMask).listAsFiles(this.baseDir); return files; } /** * If $src is defined, returns that. Else returns findFilesForPattern(). */ public List<File> getFiles() throws IOException { if (this.src != null) return Arrays.asList(this.src); else if (this.pathMask != null) return findFilesForPattern(); else return Collections.EMPTY_LIST; } }